上篇文章给大家介绍了细说webpack源码之compile流程-rules参数处理技巧(2), 细说webpack源码之compile流程-入口函数run
大家可以点击查看。
Tips:写到这里,需要对当初的规则进行修改。在必要的地方,会在webpack.config.js中设置特殊的参数来跑源码,例如本例会使用module:{rules:[...]}来测试,基本上测试参数均取自于vue脚手架(太复杂的删掉)。
下面两节的主要流程图如下:

在进入compile方法后,迎面而来的就是这么一行代码:
const params = this.newCompilationParams();
简单看一下方法,源码如下:
Compiler.prototype.newCompilationParams = () => {
const params = {
normalModuleFactory: this.createNormalModuleFactory(),
contextModuleFactory: this.createContextModuleFactory(),
compilationDependencies: []
};
return params;
}
// 工厂方法1
Compiler.prototype.createNormalModuleFactory = () => {
const normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolvers, this.options.module || {});
this.applyPlugins("normal-module-factory", normalModuleFactory);
return normalModuleFactory;
}
// 工厂方法2
Compiler.prototype.createContextModuleFactory = () => {
const contextModuleFactory = new ContextModuleFactory(this.resolvers, this.inputFileSystem);
this.applyPlugins("context-module-factory", contextModuleFactory);
return contextModuleFactory;
}
该方法生成了一个对象参数,而对象中的值又分别调用了各自的工厂方法。
按顺序,首先来看NormalModuleFactory工厂方法,首先是构造函数:
class NormalModuleFactory extends Tapable {
// context默认为命令执行路径
// resolvers => {...}
// options => options.module
constructor(context, resolvers, options) {
super();
// 该参数在WebpackOptionsApply方法中被赋值
this.resolvers = resolvers;
// 处理module.rules或module.loaders
// 两者意义一样
this.ruleSet = new RuleSet(options.rules || options.loaders);
// 谁会去设置这玩意???默认参数设置那会被置为true
// 这里会生成一个返回布尔值的函数 可以简单理解为!!
this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache);
this.context = context || "";
// 解析缓存
this.parserCache = {};
// 这两个方法超级长
this.plugin("factory", () => (result, callback) => { /**/ });
this.plugin("resolver", () => (data, callback) => { /**/ })
}
}
也是一个继承了Tapable框架的类,构造函数除去两个事件流注入不看,剩余的内容只有RuleSet那一块,也是本节的主要内容。
