原文首发于 blog.flqin.com。若有错误,请联系笔者。分析码字不易,转载请代表出处,谢谢!node
经过在 cli
执行命令 webpack
开始,以 development
模式为例,暂时忽略支线剧情(错误响应,缓存等等),只分析探索 webpack
的打包主流程。webpack
根据 npm
的规则,cli
执行 webpack
后,就会去执行 node_modules/.bin/webpack
文件即 node_modules/webpack/bin/webpack.js
。因此这里咱们的 npm scripts
中的 debug
直接调试的 node_modules/.bin/webpack
的代码。 代码中经过:git
require.resolve(packageName);
复制代码
判断是否安装了包 webpack-cli
或者 webpack-command
,经过安装的数量处理后,执行:github
require(path.resolve(path.dirname(pkgPath), pkg.bin[installedClis[0].binName]));
复制代码
即执行 node_modules/webpack-cli/bin/cli.js
,web
该文件为一个自执行函数,import-local
包用于优先选用本地包,v8-compile-cache
包用于 v8
缓存优化。npm
接下来配置了 yargs
的帮助等信息:json
require("./config/config-yargs")(yargs);
复制代码
在文件 node_modules/webpack-cli/bin/config/config-yargs.js
里能够查阅具体的配置内容。数组
而后执行:缓存
yargs.parse(process.argv.slice(2), (err, argv, output) => {
//...
});
复制代码
在 yargs.parse
的回调里执行:函数
options = require('./utils/convert-argv')(argv);
复制代码
convert-argv.js
主要作了对 cli
所传的参数与项目配置进行融合,并处理部分参数,最终获得一个 options
。
先处理了部分特定参数后(可能会有多个项目配置),而后经过一系列(findup
,interpret
)的处理,获得配置文件的路径值: /nice/wpDemo/webpack.config.js
。而后读取 webpack.config.js
这个文件后,执行:
processConfiguredOptions(options[0]);
复制代码
方法里先对 options
的类型进行了验证:
validateOptions(options);
复制代码
验证无误后,对项目配置文件进行了一系列的判断,包括是不是多数组,函数等等。最后执行:
processOptions(options);
复制代码
在该方法里,经过 ifArg
对融合了 cli
参数配置和项目配置(cli
参数优先级更高),包括 mode
,entry
等等,而后跳出 processOptions
继续执行,根据 cli
参数有没有 watch
相关而作一些处理。
processOptions
执行完后,回到 cli.js
文件执行同名方法 processOptions
,传入了融合了后的配置 options
,而后对配置中的统计信息(options.stats
)进行了处理。
最后执行:
const webpack = require('webpack');
//...
try {
compiler = webpack(options);
} catch (err) {
//...
}
复制代码
这里引入了webpack
(node_modules/webpack/lib/webpack.js
), webpack
挂载了不少内置的插件,如 BannerPlugin
等等, 而后执行 webpack
。
先经过 ajv
验证配置的每一项是否合法:
const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, options);
复制代码
而后判断若是 options
是数组则执行多个webpack(options)
,而后执行:
options = new WebpackOptionsDefaulter().process(options);
复制代码
该方法在文件 WebpackOptionsDefaulter.js
里,初始化默认的 config
配置后,而后经过 WebpackOptionsDefaulter
的原始类 OptionsDefaulter
上的 process
方法 merge
了项目配置。而后执行:
compiler = new Compiler(options.context); // options.context为当前项目绝对路径
复制代码
options
是系统默认的配置与项目自定义配置两种融合的结果,此时项目配置
与默认配置
都已处理完毕,进入编译前的准备。
webpack
先选择了 cli
后,配置了 yargs
相关信息;yarg
解析了 cli
相关参数后,与读取到的配置文件的配置相融合;stats
配置后,执行方法 webpack
,融合了项目配置与默认配置,最终获得 options
挂载到变量 compiler
下。