上文讲到调用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