webpack和webpack-cli模塊源碼分析

webpack4與webpack3的區別

webpack4.0 之後,彷佛執行方式就發生了改變,再也不是 webpack 一波流,而是多了一個 webpack-cliwebpack3webpack-cli是合在webpack中。因此在命令行運行 webpack 命令的同時,會提示讓你再裝一個 webpack-clihtml

執行腳本到打包結束流程

一、當咱們安裝了webpack模塊後,就會在node_modules/.bin目錄下生成一個webpack、webpack.cmd,webpacklinux下的命令腳本,webpack.cmdwindows下命令腳本,webpack.cmd能夠在windows系統上直接運行。node

每當執行npm run,就會自動新建一個 Shell,在這個 Shell 裏面執行指定的腳本命令。所以,只要是 Shell(通常是 Bash)能夠運行的命令,就能夠寫在 npm 腳本里面。linux

比較特別的是,npm run新建的這個 Shell,會將當前目錄的node_modules/.bin子目錄加入PATH變量(軟鏈接),執行結束後,再將PATH變量恢復原樣。webpack

這意味着,當前目錄的node_modules/.bin子目錄裏面的全部腳本,均可以直接用腳本名調用,而沒必要加上路徑。好比,當前項目的依賴裏面有 Mocha,只要直接寫mocha test就能夠了。git

// 執行一下命令
cd .\node_modules\.bin\
ls

image.png
二、package.jsonscript配置dev: webpack --mode development,當執行npm run dev至關於執行webpack --mode development
image.png
webpack.cmd執行時會判斷當前目錄下是否存在node執行程序,若是存在就使用當前node進程執行node_modules/webpack/bin/webpack.js,若是當前目錄下不存在node進程,則使用全局(也就是本地)node執行node_modules/webpack/bin/webpack.js文件
三、node_modules/webpack/bin/webpack.js首先會判斷是否安裝了webpack-cli模塊,若是沒有安裝webpack-cli模塊就會引導用戶去安裝,若是已經安裝了webpack-cli模塊,就會去執行node_modules\webpack-cli\bin\cli.jsgithub

const CLIs = [
    {
        name: "webpack-cli",
        package: "webpack-cli",
        binName: "webpack-cli",
        alias: "cli",
        installed: isInstalled("webpack-cli"),
        recommended: true,
        url: "https://github.com/webpack/webpack-cli",
        description: "The original webpack full-featured CLI."
    },
    {
        // some coding
    }
];

const installedClis = CLIs.filter(cli => cli.installed);

if (installedClis.length === 0) {
    // some coding
    const question = `Do you want to install 'webpack-cli' (yes/no): `;
    // some coding
} else if (installedClis.length === 1) {
    const path = require("path");
    const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
    const pkg = require(pkgPath);
    console.log(path.resolve(
        path.dirname(pkgPath),
        pkg.bin[installedClis[0].binName]
    )) // E:\項目\webpack學習\node_modules\webpack-cli\bin\cli.js
    require(path.resolve(
        path.dirname(pkgPath),
        pkg.bin[installedClis[0].binName]
    ));
}

四、node_modules\webpack-cli\bin\cli.js中會require("webpack")引入webpack模塊(/node_modules/lib/webpack.js)獲得一個webpack函數,運行webpack函數,返回一個compiler對象,執行compiler中的run,開始編譯web

// node_modules/bin/cli.js
(function() {
    // 一大堆配置
    // something code ...
    yargs.parse(process.argv.slice(2), (err, argv, output) => {
        // something code ...
        function processOptions(options) {
            // 各類if else 過濾和配置
            // something code...
            const webpack = require("webpack");
            let compiler;
            try {
                // 運行webpack函數,返回一個compiler對象
                compiler = webpack(options); 
            } catch (err) {
                // something code...
            }
            // 執行compiler中的run,開始編譯。
            compiler.run(compilerCallback);
        }
        processOptions(options);
    })
    // something code ...

})()
// node_modules/webpack/lib/webpack.js
const webpack = (options, callback) => {
    // some coding
    return compiler;
}
exports = module.exports = webpack;

參考:
npm 腳本的原理:http://www.ruanyifeng.com/blo...
webpack-cli源碼解析:https://www.jianshu.com/p/ec8...npm

相關文章
相關標籤/搜索