# 源码解析二

# 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-entry

# 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;
	}
	// ...
}

# 小结

  1. 执行 webpack 命令,首先 调用 webpack-li 对传入的配置参数进行校验
  2. 通过 yarg 解析了 cli 相关参数后,与读取到的配置文件的配置相融合
  3. 校验通过后 终于再次webpack 出马,传入 options 配置,并返回 compiler
更新时间: 9/23/2020, 3:25:31 PM