淺談webpack和webpack-cli模組原始碼分析
webpack4與webpack3的區別
webpack4.0
以後,似乎執行方式就發生了改變,不再是 webpack
一波流,而是多了一個 webpack-cli
。webpack3
中webpack-cli
是合在webpack
中。所以在命令列執行 webpack
命令的同時,會提示讓你再裝一個 webpack-cli
。
執行指令碼到打包結束流程
1、當我們安裝了webpack
模組後,就會在node_modules/.bin
目錄下生成一個webpack、webpack.cmd,webpack
是linux
下的命令指令碼,webpack.cmd
是windows
下命令指令碼,webpack.cmd
可以在windows
每當執行npm run
,就會自動新建一個 Shell
,在這個 Shell
裡面執行指定的指令碼命令。因此,只要是 Shell
(一般是 Bash
)可以執行的命令,就可以寫在 npm
腳本里面。
比較特別的是,npm run
新建的這個 Shell,會將當前目錄的node_modules/.bin
子目錄加入PATH
變數(軟連線),執行結束後,再將PATH
變數恢復原樣。
這意味著,當前目錄的node_modules/.bin
子目錄裡面的所有指令碼,都可以直接用指令碼名呼叫,而不必加上路徑。比如,當前專案的依賴裡面有 Mocha
,只要直接寫mocha test
就可以了。
執行一下命令 cd .\node_modules\.bin\
2、package.json
中script
配置dev: webpack --mode development
,當執行npm run dev
相當於執行webpack --mode development
webpack.cmd
執行時會判斷當前目錄下是否存在node
執行程式,如果存在就使用當前node
程序執行node_modules/webpack/bin/webpack.js
,如果當前目錄下不存在node
程序,則使用全域性(也就是本地)node
執行node_modules/webpack/bin/webpack.js
檔案
3、node_modules/webpack/bin/webpack.js
首先會判斷是否安裝了webpack-cli
webpack-cli
模組就會引導使用者去安裝,如果已經安裝了webpack-cli
模組,就會去執行node_modules\webpack-cli\bin\cli.js
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] )); }
4、node_modules\webpack-cli\bin\cli.js
中會require("webpack")
引入webpack
模組(/node_modules/lib/webpack.js
)得到一個webpack
函式,執行webpack
函式,返回一個compiler
物件,執行compiler
中的run
,開始編譯
// 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 指令碼的原理:https://www.jb51.net/article/148443.htm
webpack-cli原始碼解析:https://www.jianshu.com/p/ec8e70d362ef
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。