# 源码解析二
# webpack.js
通常我们执行 webpack 命令,就会去执行 bin/webpack.js 文件,首先可以看到去检查了 installedClis.length 的判断
const installedClis = CLIs.filter(cli => cli.installed);
if (installedClis.length === 0) {
// 提示要去安装 webpack-cli
}else{
const path = require("path");
const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
const pkg = require(pkgPath);
console.log(installedClis[0].binName + "1234456777");
require(path.resolve(
path.dirname(pkgPath),
pkg.bin[installedClis[0].binName]
));
}
这里首先会去检测 有没有安装 webpack-cli,然后会根据你本地有没有 yarn.lock 判断你有没有安装 yarn,有安装就使用 yarn 来安装 webpack-cli,没有就使用 npm 来安装,如果安装了则去加载 一个文件, 通过打印我们发现是去加载 webpacl-cli/bin/cli.js
# webpack.cli.js
首先这是一个立即执行函数, import-local 包用于优先选用本地包, require("v8-compile-cache") 用于 v8 缓存优化
# yargs
首先 加载了 yargs
const yargs = require("yargs").usage(`webpack-cli ${require("../package.json").version}
然后配置了一些帮助信息:
require("./config/config-yargs")(yargs);
所有的信息可以去 webpack-cli/bin/config/config-yargs.js 里面查看
然后执行 解析参数的命令
yargs.parse(process.argv.slice(2), (err, argv, output) => {
let options;
try {
options = require("./utils/convert-argv")(argv);
} catch (err) {
}
}
这里可以看到 yargs 根据我们的启动 webpack 的命令(携带命令) 去解析参数,然后我们再去 convert-argv.js 具体看看
const argv = args[1] || args[0];
const options = [];
// Shortcuts
if (argv.d) {
argv.debug = true;
argv["output-pathinfo"] = true;
if (!argv.devtool) {
argv.devtool = "eval-cheap-module-source-map";
}
if (!argv.mode) {
argv.mode = "development";
}
}
if (argv.p) {
if (!argv.mode) {
argv.mode = "production";
}
}
if (argv.output) {
}
let i;
if (argv.config) {
// ...
} else {
const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|");
const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`;
const pathToWebpackConfig = findup(webpackConfigFileRegExp);
if (pathToWebpackConfig) {
const resolvedPath = path.resolve(pathToWebpackConfig);
const actualConfigFileName = path.basename(resolvedPath);
const ext = actualConfigFileName.replace(new RegExp(defaultConfigFileNames), "");
configFiles.push({
path: resolvedPath,
ext
});
}
}
}
这个文件对 webpack 的配置做了详细的检测,最后返回给上层 options,如果出现配置错误❌,就根据对应的一一抛出错误.
# processOptions
在 cli.js 文件的最后看到执行了这么一个函数
processOptions(options){
// ...
ifArg("env", function (value) {
if (outputOptions.env) {
outputOptions._env = value;
}
});
...
}
processOptions 前面对传入的 options 进行了一系列的校验,检测合并等等的干活,终于我们看到正活了,如下:
function processOptions(options) {
// ...
const webpack = require("webpack");
let compiler;
try {
compiler = webpack(options);
} catch (err) {
throw err;
}
// ...
}
# 小结
- 执行 webpack 命令,首先 调用 webpack-li 对传入的配置参数进行校验
- 通过 yarg 解析了 cli 相关参数后,与读取到的配置文件的配置相融合
- 校验通过后 终于再次webpack 出马,传入 options 配置,并返回 compiler