请问:vite如何手动分包?

254 阅读3分钟

先讲 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 文件变了,浏览器缓存就失效了,用户又要重新加载整个大文件,浪费流量又加载慢

  1. 缓存优化:将第三方库(vendor)与业务代码分离,当修改业务代码时,第三方库的文件指纹不变,浏览器可以继续使用缓存
  2. 减小更新体积:只重新加载变化的业务代码部分,而不是整个打包文件

所以我们希望:

  • 自己写的代码打一个包
  • 第三方库打一个或多个包
  • 这样你改自己的代码,三方库不变,浏览器就能复用老缓存

怎么配置手动分包?

1️⃣ 基础版:手动列出要分包的库名

方法一:显式配置第三方

image.png

// 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 的包:

image.png

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 文件的指纹),这样用户加载快、体验好。


🔍 总结

分包后的优势

  1. 缓存利用率高:第三方库变更频率低,可以长期缓存
  2. 加载性能提升:用户只需要下载变化的业务代码部分
  3. 构建效率提高:未修改的第三方库不需要重新处理

注意事项

  1. 过度分包可能导致 HTTP/2 的多路复用优势减弱
  2. 对于小型项目,分包可能带来的优化效果有限
配置方式用法优点
manualChunks: { vendor: ['vue', 'lodash'] }手动指定库名分包精确控制,适合小项目
manualChunks(id) { if (id.includes('node_modules')) return 'vendor' }自动识别第三方库分包自动智能,适合大项目