一文搞懂 Webpack 分包:async、initial 与 all 的区别【附源码】

大家好,我是前端架构师 ,关注微信公众号【程序员大卫】免费领取精品资料。

1. 背景

最近在优化一个项目的加载性能时,对 optimization.splitChunks.chunks 的三个可选值 async、initial 和 all 的具体效果产生了疑惑。为了彻底搞清楚它们的区别,我专门搭建了一个 Demo 进行对比研究。

2. 核心区别:async vs initial

chunks 属性决定了 Webpack 对哪些类型的代码块进行分割。其中 async 是默认配置。

经过测试发现:在单入口应用中,二者区别不明显;但在多入口应用中,差异非常显著。

2.1 测试环境配置 (webpack.config.js)

为了直观观察分包结果,我将 minSize 设置为 0,确保即使是很小的模块也会被强制分割。

javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "production",
  entry: {
    entry1: "./src/entry1.js",
    entry2: "./src/entry2.js",
  },
  optimization: {
    splitChunks: {
      chunks: "async", // 实验变量:此处分别修改为 'async', 'initial', 'all'
      minSize: 0       // 强制分割小模块
    },
  },
  plugins: [
    new CleanWebpackPlugin() // 每次构建前清理 dist 目录
  ],
};

2.2 代码结构

假设我们有两个入口文件,它们都引用了同步模块 shared.js,且 entry1 额外引用了一个异步模块 dynamic.js。

  • entry1.js : 引用 shared + 动态引用 dynamic
  • entry2.js : 引用 shared
javascript 复制代码
// entry1.js
import "./shared";       // 同步公共模块
import("./dynamic");     // 异步动态导入
console.log("entry1");

// entry2.js
import "./shared";       // 同步公共模块
console.log("entry2");

2.3 打包结果对比

在上述场景下,切换配置会产生完全不同的结果:

  • 设置 chunks: 'async' (默认)

    • 结果 :dynamic.js 被单独打包,但 shared.js 没有被分离。
    • 原因 :async 只关注异步加载(动态导入)的模块。尽管 shared.js 被多个入口引用,但因为它是同步导入的,所以被忽略,直接打入了各自的入口包中。
  • 设置 chunks: 'initial'

    • 结果 :dynamic.js 被单独打包,同时 shared.js 也可以被剥离出来成为独立文件。
    • 原因 :initial 关注初始加载(同步导入)的模块。Webpack 发现 shared.js 在初始化时就被多个入口共享,因此将其分离。

3. 关于 all

当设置为 all 时,Webpack 会采用一种混合策略:无论同步还是异步,只要满足分割条件(如大小、引用次数),都会进行代码分割。

这是目前最推荐的配置,因为它能最大限度地复用代码,减小包体积。

4. 总结

三种模式的核心差异对比:

模式 作用范围 适用场景 特点
async (默认) 仅异步模块 针对 import() 动态导入的模块 确保首屏加载的 bundle 纯净,不影响初始包大小
initial 仅同步模块 针对入口文件直接 import 的公共模块 优化多页应用的公共代码提取,减少重复打包
all 所有模块 希望最大化代码分割效果 最全面的策略,通常能获得最佳的缓存利用率

源码地址: github.com/zm8/wechat-...

相关推荐
jktantan1 小时前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
2601_962885722 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
excel2 小时前
encodeURI 和 encodeURIComponent 有什么区别?
前端
前端精髓2 小时前
调用openrouter的免费API模型
java·前端·javascript
赛博守夜人3 小时前
AI安全攻防与治理之十四:AI 安全测试不能脱离传统安全,Web、API、移动端与模型攻击面的组合拳
前端·人工智能·安全
开开心心_Every3 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
networknomad3 小时前
OpenReplay:自己搭的会话回放工具,给前端排错用的
前端·其他
缓慢更新4 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
陈随易4 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员
风骏时光牛马5 小时前
AI稳定性治理体系构建与疑难问题深度分析
前端