Skip to content

webpack ​

webpack工作原理 ​

  1. webpack通过执行bin目录下的入口文件,在入口文件内判断并调用webpack-cli。
  2. 在webpack-cli里面,收集命令行和配置文件的参数,对参数进行处理生成选项参数。然后进行webpack实例化。
  3. webpack实例里面执行构建步骤,构建步骤分为初始化阶段、构建阶段、生成阶段
  4. 初始化阶段,生成Complier实例,加载所有配置的插件。
    • Compiler:全局单例,包含 Webpack 环境的所有配置信息(如 loader、plugin)。
    • Compilation:每次构建生成一个新实例,包含当前构建的模块、依赖和资源信息
  5. 构建阶段,首先会entry开始,分析出模块modules之间的依赖关系,生成依赖图。然后调用loader对各种文件进行转换,比如对JS转换为AST语法树。最后将AST语法树转换为modules。
    • 递归解析:从入口文件开始,深度优先遍历所有依赖(包括动态导入)。
    • Loader 链式调用:loader 按逆序执行(如 use: ['style-loader', 'css-loader'])。
    • AST 转换:Babel 等工具将 JS 转换为 AST 后,可通过插件修改(如 Tree Shaking)。
  6. 生成阶段,这个阶段会进行代码的切割和合并,将modules转换为chunks。最终会将chunks输出为最终的bundle文件。
    • Module:源码中的一个文件(如 ./src/App.js)。
    • Chunk:打包后的逻辑单元,由多个 module 组成(如入口 chunk、动态导入 chunk)。
  7. webpack会在上述过程中广播特定事件,plugin可以调用API改变webpack的运行结果。
    • HtmlWebpackPlugin:在 compilation 阶段生成 HTML。
    • MiniCssExtractPlugin:在 optimize-chunk-assets 阶段提取 CSS。
    • TerserPlugin:在 optimize-minimize 阶段压缩代码。

source-map ​

source-map文件不打开控制台,是不会加载的。

建议 ​

开发环境 ​

  1. 首选:eval-cheap-module-source-map
    • 兼顾构建速度和调试体验,支持查看 loader 处理前的原始代码。
  2. 对构建速度敏感的项目:eval 或 eval-cheap-source-map
    • 牺牲部分调试精度换取极致性能。

生产环境 ​

  1. 不发布 Source Map(默认)
    • 安全性最高,但无法调试线上问题。
  2. 仅后端使用:hidden-source-map
    • 生成独立的 Source Map,但不在 JS 文件中引用。
    • 用途:结合错误监控工具(如 Sentry),仅在后端收集错误时使用 Source Map 解析堆栈。
  3. 特殊场景:nosources-source-map
    • 生成不含原始代码的 Source Map(仅包含映射信息)。
    • 用途:暴露错误位置但保护源代码隐私。
  4. 如果配置source-map,则需要结合nginx,只对内网开放,以便于调试。

按性能分类的 Source Map 选项 ​

  1. 最快的选项(开发环境推荐)
    • eval
      • 特点:每个模块被 eval 包裹,并在末尾添加 //# sourceURL。
      • 优势:构建速度最快(几乎无额外开销)。
      • 劣势:仅映射行号,不支持列映射;无法调试原始文件内容。
      • 适用场景:对构建速度要求极高的大型项目。
    • eval-cheap-source-map
      • 特点:生成行映射的 Source Map,内嵌到 eval 语句中。
      • 优势:比 eval 提供更精确的错误位置(支持行映射)。
      • 劣势:不支持列映射,无法调试原始代码(只能看到编译后的代码)。
      • 适用场景:需要快速构建且对列调试需求不高的场景。
  2. 平衡选项(开发环境常用)
    • eval-cheap-module-source-map
      • 特点:生成行映射的 Source Map,包含 loader 处理前的原始模块信息。
      • 优势:构建速度较快,支持调试 loader 处理前的原始代码(如 Babel 转换前)。
      • 劣势:仅支持行映射。
      • 适用场景:大多数开发环境的首选,兼顾速度和调试体验。
  3. 最精确的选项(生产环境可选)
    • source-map
      • 特点:生成独立的 Source Map 文件,包含完整的行列映射和原始代码。
      • 优势:调试体验最佳,支持断点调试和变量查看。
      • 劣势:构建和重建速度最慢,增加额外文件体积。
      • 适用场景:生产环境需要调试线上代码时(需谨慎暴露)。
    • inline-source-map
      • 特点:将 Source Map 以 Base64 形式内嵌到 JS 文件中。
      • 优势:无需额外文件,方便部署。
      • 劣势:大幅增加 JS 文件体积,性能影响较大。
      • 适用场景:小型应用或测试环境。

热更新 ​

  • 通过配置watch:true开启。webpack会轮询文件是否改变,并记录下来。
  • 而浏览器和服务器会实现一个websocket链接,
  • 当文件打包完成后,会通知浏览器,并携带构建的hash,浏览器会与本地hash做对比,
  • 然后浏览器会通过jsonp请求需要变更的文件。拿到文件后浏览器会通过hotModuleReplace进行刷新页面还是部分替换内容。

tree-shaking ​

  • 通过将代码转换为AST语法树,然后通过变量语法树,对未遍历的位置语法树进行剪枝,即将未遍历的代码进行删除。
  • webpack和rollup原理类似,但是webpack会在打包的时候进行依赖图分析,需要考虑更多边界情况。