先讲 vite的底层 rollup
vite 底层是用 rollup写的 ,很多时候要去查看rollup文档。
Rollup 的核心优势:
• Tree-shaking:Rollup 的静态分析能力极强,能精准剔除未使用的代码(Dead Code Elimination),生成更小的产物体积。
• 输出格式灵活:支持 ESM、CommonJS、IIFE 等多种模块格式,适合不同场景。
• 插件生态兼容:Vite 可以直接复用 Rollup 插件(需少量适配),生态互通。
• 稳定性与成熟度:Rollup 是久经考验的打包工具,适合生产环境的高标准需求。
在 Vite 中实现 手动分包(manual chunking),主要是通过配置 build.rollupOptions.output.manualChunks 来完成的。这段配置实际上是 Rollup 提供的功能,Vite 在打生产包时是基于 Rollup 的。
为什么要手动分包?
默认情况下,Vite 会把你写的代码和用到的三方库(比如 Vue、lodash)全都打包在一个 JS 文件里。如果你哪天只改了一点你自己的代码,那也会导致整个大 JS 文件变了,浏览器缓存就失效了,用户又要重新加载整个大文件,浪费流量又加载慢。
- 缓存优化:将第三方库(vendor)与业务代码分离,当修改业务代码时,第三方库的文件指纹不变,浏览器可以继续使用缓存
- 减小更新体积:只重新加载变化的业务代码部分,而不是整个打包文件
所以我们希望:
- 自己写的代码打一个包
- 第三方库打一个或多个包
- 这样你改自己的代码,三方库不变,浏览器就能复用老缓存
怎么配置手动分包?
1️⃣ 基础版:手动列出要分包的库名
方法一:显式配置第三方
// vite.config.ts
export default {
build: {
rollupOptions: {
output: {
manualChunks: {
// 把 Vue 和 Lodash 单独打到一个包里,叫做 "vendor"
vendor: ['vue', 'lodash'],
},
},
},
},
};
📦 打完包后,你会看到:
assets/vendor.xxx.js(三方库)assets/index.xxx.js(你自己的代码)
2️⃣ 进阶版:自动识别 node_modules 的内容统一分包
方法二:使用函数动态分包(推荐)
你不想一个个列出来?那就用函数方式判断哪些模块在 node_modules,都统一放进一个叫 vendor 的包:
export default {
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor'; // 把所有三方库打进 vendor 包
}
},
},
},
},
};
✅ 效果:
- 你自己的代码打一个包
- 所有第三方库自动打进一个叫
vendor的大包 - 只要你没升级第三方库,vendor 的指纹就不会变
更精细的分包:
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('vue')) {
return 'vue' // 将 vue 单独打包
}
if (id.includes('lodash')) {
return 'lodash' // 将 lodash 单独打包
}
return 'vendor' // 其他第三方库打包到一起
}
}
🧐 文件指纹为什么重要?
你打包后每个文件名都会有一串 hash 指纹,比如:
index.ab12cd.js
vendor.34ef56.js
一旦内容变了,文件名就变了。
浏览器缓存是根据文件名判断的,所以我们就要让变动只影响一小部分的文件名(比如你改了一点点业务逻辑,就只改 index 文件的指纹),这样用户加载快、体验好。
🔍 总结
分包后的优势
- 缓存利用率高:第三方库变更频率低,可以长期缓存
- 加载性能提升:用户只需要下载变化的业务代码部分
- 构建效率提高:未修改的第三方库不需要重新处理
注意事项
过度分包可能导致 HTTP/2 的多路复用优势减弱- 对于
小型项目,分包可能带来的优化效果有限
| 配置方式 | 用法 | 优点 |
|---|---|---|
manualChunks: { vendor: ['vue', 'lodash'] } | 手动指定库名分包 | 精确控制,适合小项目 |
manualChunks(id) { if (id.includes('node_modules')) return 'vendor' } | 自动识别第三方库分包 | 自动智能,适合大项目 |