上篇文章给大家介绍了细说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那一块,也是本节的主要内容。