Skip to main content

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):

  1. 初始化阶段 (Init)
    • 读取合并配置:读取 webpack.config.js 和 shell 参数,合并得到最终配置。
    • 实例化 Compiler:用上一步得到的参数初始化 Compiler 对象。
    • 注册插件:加载所有配置的插件,执行对象的 apply 方法,挂载对应的生命周期 Hook。
  2. 编译阶段 (Make)
    • 确定入口:根据配置中的 entry 找出所有的入口文件,调用 Compiler.run 开始构建。
    • 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行转译。
    • 解析依赖:将转译后的模块解析为 AST(抽象语法树),找出该模块依赖的其他模块(如 import 语句)。
    • 递归编译:递归执行上述步骤,直到所有入口依赖的文件都经过了本步骤的处理。
  3. 输出阶段 (Seal)
    • 合并 Chunk:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk。
    • 生成资产 (Assets):将 Chunk 转换成一个单独的文件加入到输出列表(此时还可以通过 Plugin 修改输出内容)。
    • 写入文件系统:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

Webpack 5 核心特性

  • 持久化缓存 (Persistent Caching):内置了文件系统缓存能力,大幅提升二次构建速度(替代了之前的 cache-loader / hard-source-webpack-plugin)。
  • 更优的 Tree Shaking:能够处理嵌套模块的导出,并提供更智能的代码消除能力。
  • 模块联邦 (Module Federation):允许多个独立的构建(独立的应用)在运行时互相共享模块,是微前端架构的重要基础。
  • Asset Modules (资源模块):内置了对字体、图片等静态资源的处理,无需再配置 file-loaderurl-loaderraw-loader
  • 确定的 Chunk/Module ID:默认开启长期缓存优化,避免了由于模块增删导致 ID 变化进而引起缓存失效的问题。

核心原理探究

Tree Shaking 原理

Tree Shaking 指的是移除 JavaScript 上下文中的未引用代码(dead-code)。

  • 基础:依赖于 ES Modules (ESM) 的静态语法分析特性(importexport 是在编译时确定的,不能在运行时按条件引入)。
  • 过程
    1. Webpack 在构建依赖图时,会标记模块导出的值是否被使用。
    2. optimization.usedExports 开启的情况下(生产模式默认开启),生成代码时会添加魔法注释以标记未使用的代码。
    3. 最终由代码压缩工具(如 Terser)在压缩阶段将这些未使用的“死代码”彻底删除。
  • 副作用 (Side Effects):某些模块虽然没有被显式调用导出成员,但只要执行就会对全局环境产生影响(如 polyfill、全局 CSS)。需要在 package.json 中配置 "sideEffects": false 明确告知 Webpack 哪些文件没有副作用,以便安全剔除。