上文講到調用webpack指令實際運行的是node webpack\bin\webpack.js這段代碼,咱們今天的目的就是分析webpack\bin\路徑下的webpack.js文件node
// 將 webpack.js 中的源碼主體扣出來並添加註釋 process.exitCode = 0; // 定義命令執行函數 const runCommand = (command, args) => { // ... } // 定義判斷包是否安裝函數 const isInstalled = packageName => { // ... } // 定義cli數組 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." }, { name: "webpack-command", package: "webpack-command", binName: "webpack-command", alias: "command", installed: isInstalled("webpack-command"), recommended: false, url: "https://github.com/webpack-contrib/webpack-command", description: "A lightweight, opinionated webpack CLI." } ]; // 執行cli數組中每一項的installed方法 const installedClis = CLIs.filter(cli => cli.installed); // 根據返回值installedClis長度執行對應邏輯 if (installedClis.length === 0) { // ... }else if (installedClis.length === 1) { // ... }else { // ... }
代碼簡化以後更方便咱們理解他的做用,如今咱們來逐步分析這塊代碼的執行過程:webpack
const installedClis = CLIs.filter(cli => cli.installed);
isInstalled("webpack-cli") isInstalled("webpack-command") const isInstalled = packageName => { try { require.resolve(packageName); return true; } catch (err) { return false; } }; // require.resolve函數會查詢模塊的帶有完整路徑的文件名,但並不會加載該模塊。 // 因爲咱們項目中只安裝了webpack-cli,因此installedClis的值爲[ true ]。
// 如下爲簡化代碼 // 當installedClis的length爲0時,則會提示用戶必須安裝一個webpack的cli模塊並引導用戶安裝webpack-cli if (installedClis.length === 0) { let notify = "One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:"; for (const item of CLIs) { if (item.recommended) { notify += `\n - ${item.name} (${item.url})\n ${item.description}`; } } console.error(notify); console.error( `We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join( " " )}".` ); let question = `Do you want to install 'webpack-cli' (yes/no): `; } else if (installedClis.length === 1) { // ... } else { // ... } // 當installedClis的length爲2時,會提示用戶只能安裝一個webpack的cli庫,用戶須要卸載其中之一。 if (installedClis.length === 0) { // ... } else if (installedClis.length === 1) { // ... } else { console.warn( `You have installed ${installedClis .map(item => item.name) .join( " and " )} together. To work with the "webpack" command you need only one CLI package, please remove one of them or use them directly via their binary.` ); } // 當installedClis的length爲1時 if (installedClis.length === 0) { // ... } else if (installedClis.length === 1) { // 獲取webpack-cli/package.json文件完整路徑 const pkgPath = require.resolve(`${installedClis[0].package}/package.json`); // 引入webpack-cli/package.json 包文件 const pkg = require(pkgPath); // 引入webpack-cli/bin/cli.js 模塊 require(path.resolve( path.dirname(pkgPath), pkg.bin[installedClis[0].binName] )); } else { // ... }
經過上面的分析,webpack.js文件最終的目的就是引入 webpack-cli/bin/cli.js 模塊。git
ok,下一篇cli.js見!github