咳咳。。外出玩了一周,是时候回来补东西了。之前看的webpack.js写了一半了,现在继续。
上周我们刚讲完webpack-cli.js
的processOptions
函数:
function processOptions(options) {
// 各种if else 过滤和配置
// something code...
let compiler;
try {
compiler = webpack(options); // 注释1
} catch (err) {
// something code...
}
compiler.run(compilerCallback); // 注释2
}
这里有两个关键点:
注释1:执行webpack函数
,得到一个compiler。
注释2:执行compiler.run()
方法。
由于这俩段代码都不属于webpack-cli.js
的内容,所以才推到webpack.js
这里讲。
webpack:
// 一大堆引入
// something code ...
const webpack = (options, callback) => {
// something code ...
let compiler;
if(Array.isArray(options)) {
compiler = new MultiCompiler(options.map(options => webpack(options)));
} else if(typeof options === 'object') {
options = new WebpackOptionsDefaulter().process(options); // 将配置与默认配置合并
compiler = new Compiler(options.context); // 将上下文传进编译器中编译
compiler.options = options; // 设置编译器的配置
new NodeEnvironmentPlugin().apply(compiler); // 使用node风格文件的系统编译
if (options.plugins && Array.isArray(options.plugins)) { // 如果配置项有插件,安装插件
for (const plugin of options.plugins) {
plugin.apply(compiler);
}
}
compiler.hooks.environment.call(); // 在environment环境配置的时候要执行的钩子
compiler.hooks.afterEnvironment.call(); // 在environment环境配置之后要执行的钩子
compiler.options = new WebpackOptionsApply().process(options, compiler); // 对大量的参数进行了处理,并注册了大量的编译所需要用到的插件
} else {
// 抛出错误
// something code ...
}
if(callback) {
// something code ...
}
return compiler;
};
首先看最外一层webpack函数
,它会return一个compiler对象
。
而这个compiler对象
就是暴露给webpack-cli.js
使用的。
基本的步骤就是如下,先判断是否配置多个compiler对象
,多个其实就是将配置多个compiler对象
用一个class封装了起来,这里我们先看配置单个的:
1、将传入配置与默认配置合并:
options = new WebpackOptionsDefaulter().process(options);
2、将上下文传进编译器中编译
compiler = new Compiler(options.context);
3、设置编译器的配置
compiler.options = options;
4、使用node风格文件的系统编译
new NodeEnvironmentPlugin().apply(compiler);
5、如果配置项有插件,安装插件
if (options.plugins && Array.isArray(options.plugins)) {
for (const plugin of options.plugins) {
plugin.apply(compiler);
}
}
6、在environment环境配置的时候要执行的钩子
compiler.hooks.environment.call();
7、在environment环境配置之后要执行的钩子
compiler.hooks.afterEnvironment.call();
8、对大量的参数进行了处理,并注册了大量的编译所需要用到的插件
compiler.options = new WebpackOptionsApply().process(options, compiler);
9、未知这个callback,以及传入callback时执行run的用处
if (callback) { // 未知这个callback,以及传入callback时执行run的用处
if (typeof callback !== "function")
throw new Error("Invalid argument: callback");
if (
options.watch === true ||
(Array.isArray(options) && options.some(o => o.watch))
) {
const watchOptions = Array.isArray(options)
? options.map(o => o.watchOptions || {})
: options.watchOptions || {};
return compiler.watch(watchOptions, callback);
}
compiler.run(callback);
}
10、webpack函数最底部,返回编译器compiler
由外部执行run
return compiler;
剩下外边的都是对插件的一些处理,不影响主要执行流程。
到了这里,webpack.js
就能和webpack-cli.js
联系起来了,相信能读到这里的也对webpack初步执行有一个清晰的概念了吧。
这一波webpack探索就到这里了,下一章是compiler.js,溜了溜了。