构建流程和原理
2024-11-28
构建流程和原理
Webpack 的核心能力就是静态模块打包能力。Webpack 能够将各种类型的资源 —— 包括图片、音视频、CSS、JavaScript 代码等,通通转译、组合、拼接、生成标准的、能够在不同版本浏览器兼容执行的 JavaScript 代码文件
构建流程
1.初始化
- 初始化参数:从配置文件、 配置对象、Shell 参数中读取,与默认配置结合得出最终的参数;
- 创建编译器对象 Compiler:用上一步得到的参数创建 Compiler 对象, 其中存储了配置信息,挂载了许多生命周期 hook。
- 初始化编译环境:包括注入内置插件、注册各种模块工厂、初始化 RuleSet 集合、加载配置的插件等;
- 开始编译:执行 compiler 对象的 run 方法,创建 Compilation 对象,调用 compiler.compile 方法开始执行构建。
- 确定入口:根据配置中的 entry 找出所有的入口文件,调用 compilation.addEntry 将入口文件转换为 dependence 对象。把入口文件的绝对路径添加到依赖数组,记录此次编译依赖的模块。
2.构建
- 编译模块(make) :从 entry 文件开始,调用 loader 将模块转译为标准 JS 内容(如sass转译css、ts转译js等),调用 JS 解析器 Acorn (opens new window)将内容转换为 AST 对象,从中找出该模块依赖的模块,再 递归 处理这些依赖模块,直到所有入口依赖的文件都经过了本步骤的处理;
- 完成模块编译:上一步递归处理所有能触达到的模块后,得到了每个模块被翻译后的内容以及它们之间的依赖关系图 -
ModuleGraph
。构建阶段经历了module => ast => dependences => module
的流转,先将源码解析为 AST 结构,再在 AST 中遍历 import 等模块导入语句,收集模块依赖数组 ——dependences
,最后遍历dependences
数组将Dependency
转换为Module
对象,之后递归处理这些新的Module
,添加至ModuleGraph
,直到所有项目文件处理完毕。
3.封装
- 合并(seal) :根据入口和模块之间的依赖关系,模块转译,收集运行时依赖(其实在上一阶段就已经进行了,基于静态代码分析的方式收集运行时依赖),将模块代码与运行时代码合并,组装成一个个包含多个模块的 Chunk;
- 优化(optimization) :对上述 Chunk 施加一系列优化操作,包括:tree-shaking、terser、scope-hoisting、压缩、Code Split 等;
- 写入文件系统(emitAssets) :在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统,生成 Bundle IIFE。