Webpack
核心概念
Webpack 是一个静态模块打包工具。它会在内部从一个或多个入口点构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个 bundles。
- Entry(入口):指示 Webpack 应该使用哪个模块来作为构建其内部依赖图的开始。
- Output(输出):告诉 Webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
- Module(模块):在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk(代码块):一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader(加载器):Webpack 只能理解 JavaScript 和 JSON 文件。Loader 让 Webpack 能够去处理其他类型的文件,并将它们转换为有效模块。
- Plugin(插件):用于执行范围更广的任务,包括打包优化、资源管理、注入环境变量等。
构建流程 (生命周期)
Webpack 的运行过程是一个串行的过程,从启动到结束会依次执行以下三大阶段(Init -> Make -> Seal):
- 初始化阶段 (Init)
- 读取合并配置:读取 webpack.config.js 和 shell 参数,合并得到最终配置。
- 实例化 Compiler:用上一步得到的参数初始化
Compiler对象。 - 注册插件:加载所有配置的插件,执行对象的
apply方法,挂载对应的生命周期 Hook。
- 编译阶段 (Make)
- 确定入口:根据配置中的
entry找出所有的入口文件,调用Compiler.run开始构建。 - 编译模块:从入口文件出发,调用所有配置的
Loader对模块进行转译。 - 解析依赖:将转译后的模块解析为 AST(抽象语法树),找出该模块依赖的其他模块(如
import语句)。 - 递归编译:递归执行上述步骤,直到所有入口依赖的文件都经过了本步骤的处理。
- 确定入口:根据配置中的
- 输出阶段 (Seal)
- 合并 Chunk:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk。
- 生成资产 (Assets):将 Chunk 转换成一个单独的文件加入到输出列表(此时还可以通过 Plugin 修改输出内容)。
- 写入文件系统:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
Webpack 5 核心特性
- 持久化缓存 (Persistent Caching):内置了文件系统缓存能力,大幅提升二次构建速度(替代了之前的
cache-loader/hard-source-webpack-plugin)。 - 更优的 Tree Shaking:能够处理嵌套模块的导出,并提供更智能的代码消除能力。
- 模块联邦 (Module Federation):允许多个独立的构建(独立的应用)在运行时互相共享模块,是微前端架构的重要基础。
- Asset Modules (资源模块):内置了对字体、图片等静态资源的处理,无需再配置
file-loader、url-loader、raw-loader。 - 确定的 Chunk/Module ID:默认开启长期缓存优化,避免了由于模块增删导致 ID 变化进而引起缓存失效的问题。
核心原理探究
Tree Shaking 原理
Tree Shaking 指的是移除 JavaScript 上下文中的未引用代码(dead-code)。
- 基础:依赖于 ES Modules (ESM) 的静态语法分析特性(
import和export是在编译时确定的,不能在运行时按条件引入)。 - 过程:
- Webpack 在构建依赖图时,会标记模块导出的值是否被使用。
- 在
optimization.usedExports开启的情况下(生产模式默认开启),生成代码时会添加魔法注释以标记未使用的代码。 - 最终由代码压缩工具(如 Terser)在压缩阶段将这些未使用的“死代码”彻底删除。
- 副作用 (Side Effects):某些模块虽然没有被显式调用导出成员,但只要执行就会对全局环境产生影响(如 polyfill、全局 CSS)。需要在
package.json中配置"sideEffects": false明确告知 Webpack 哪些文件没有副作用,以便安全剔除。