1 主要事件结点
Webpack 主要的事件结点如下:
entry-option
初始化optionrun
make
从 entry 分析模块及其依赖的模块,对每个依赖模块进行 buildbefore-resolve
对模块位置进行解析build-module
构建模块normal-module-loader
将 loader 加载完成的 module 进行编译,生成 AST 树program
遍历 AST,收集依赖seal
所有依赖 build 完成,进行优化emit
把各个 chunk 输出到结果文件
2 实现细节
2.1 编译与构建主流程
- 初始化阶段:根据配置初始化插件
- 通过 entry 找到入口文件,然后:
- 调用各个 loader 处理模块之间的依赖:比如 url-loader、jsx-loader、css-loader 等等来让我们可以直接在源文件中引用各类资源。… 最后生成一个 js module。
- 调用 acron 解析经 loader 处理后的源文件生成抽象语法树
- 遍历 AST,构建该模块所依赖的模块:将 require 中的模块添加到依赖中,递归前面的步骤。
- 输出文件资源
2.2 Compilation
- compiler 调用 compilation 的生命周期方法
EntryPlugin
调用compilation.addEntry
添加入口- NormalModuleFactory
compilation.factorizeQueue
调用compilation._factorizeModule
compilation.handleModuleCreation
compilation.addModule
compilation.buildModule
NormalModule.build
-
2.3 Module
可以理解为一个JS文件对应一个module, 可以分为:
NormalModule
- ContextModule:
./src/a
- ExternalModule:
module.exports = jQuery
- DelegatedModule
-
2.3.1 NormalModule
doBuild
loader-runner::runLoaders
-
2.4 Chunk
chunk 生成算法:
从 entry 开始创建新的 chunk
- 将依赖的 module 添加到 chunk 里面
- 如果遇到动态 import,创建新的 chunk
- 重复上面步骤直到结束
参考
- [1] 细说 webpack 之流程篇
- [2] Webpack 原理浅析