「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
前言
在上一文中我们重点分析了Compiler类,了解了其中的生命周期钩子的触发时机。这一期我们来了解一下webpack的另一个核心类Compilation。
源码学习
这个类的核心逻辑在于,依次进入每一个entry文件,按照依赖关系,利用各种loader对文件进行编译。
1. constructor 方法
在这个方法中,利用tapable库的各种方法声明了多个hook,然后进行了大量属性的初始化。这个方法的核心点在于这几个构建队列,对webpack的modules进行处理,编译生成chunks。
this.addModuleQueue = new AsyncQueue({
...
});
this.factorizeQueue = new AsyncQueue({
...
});
this.buildQueue = new AsyncQueue({
...
});
this.rebuildQueue = new AsyncQueue({
...
});
2. 缓存 cache
这里有个重要的东西就是缓存,大家之前应该或多或少的接触到webpack进行打包构建的时候会进行缓存。在进行compilition之前会通过getCache调取compile.getCache方法进行缓存的获取,具体缓存的使用条件涉及到了CacheFacade类了,这里我们就暂且先不提,留待后续了解。
3. module模块
module涉及了多个方法对module进行处理:addModule、getModule、findModule、buildModule。通过addModule方法,将关联的module推入到addModuleQueue队列中。同样的,通过buildModule方法,将对应的需要构建的模块推入到buildQueue队列中去。
4. addEntry
通过addEntry方法添加编译入口,然后进行打包编译。在这个方法中通过触发addModuleTree方法进行依赖树的查找。
5. finish 方法
上次我们探索Compiler类的时候,其中说到在compiler的时候触发了compilition.finish方法(就是这个方法)。在这里其实进行的是compiliton完成之后的处理。可以看到的是,在这个方法中进行了factorizeQueue队列的清空,模块依赖的清理,以及进行对应的生命周期钩子的触发。
6. seal 方法
在commpiler完成之前还触发了一个生命周期钩子compilition.seal,在这里开始进行真正的编译。在编译完成之后,还进行了收尾处理。
const finalCallback = err => {
this.factorizeQueue.clear();
this.buildQueue.clear();
this.rebuildQueue.clear();
this.processDependenciesQueue.clear();
this.addModuleQueue.clear();
return callback(err);
};
结语
进行Compilition类的分析的时候,发现之前分析Compiler的时候漏掉了某个点,导致编译流程有点不通畅。我打算后面对 compiler.hooks.make - compilation.finish() 中间的部分进行深入的研究一下。
好了,这篇文章就水到这里了,欢迎小伙伴进行讨论。