webpack原始碼分析(2)---- webpack\bin\webpack.js
阿新 • • 發佈:2019-06-04
前言
上文講到呼叫webpack指令實際執行的是node webpack\bin\webpack.js這段程式碼,我們今天的目的就是分析webpack\bin\路徑下的webpack.js檔案
原始碼
// 將 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 { // ... }
分析
程式碼簡化之後更方便我們理解他的作用,現在我們來逐步分析這塊程式碼的執行過程:
第一步
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== 模組。
o