Vite默认拆包策略
Vite 中已经内置了一份拆包的策略,在生产环境下 Vite 完全利用 Rollup 进行构建,因此拆包也是基于 Rollup 来完成的,但Rollup 本身是一个专注 JS 库打包的工具,对应用构建的能力还尚为欠缺,Vite 正好是补足了 Rollup 应用构建的能力,在拆包能力这一块的扩展就是很好的体现。
Vite 2.9 之前的版本, 在初始化一个项目后,执行 npm run build,接着终端会出现如下的构建信息:

Vite 默认拆包的优势在于实现了 CSS 代码分割与业务代码、第三方库代码、动态 import 模块代码三者的分离,但缺点也比较直观,第三方库的打包产物容易变得比较臃肿,上述例子中的 vendor.js 的大小已经达到 500 KB 以上,显然是有进一步拆包的优化空间的,这个时候我们就需要用到 Rollup 中的拆包 API —— manualChunks 了。
Vite自定义拆包策略
针对更细粒度的拆包,Vite 的底层打包引擎 Rollup 提供了 manualChunks ,让我们能自定义拆包策略,它属于 Vite 配置的一部分,示例如下:
// vite.config.ts
export default {
build: {
rollupOptions: {
output: {
// manualChunks 配置
manualChunks: {},
},
}
},
}
manualChunks 主要有两种配置的形式,可以配置为一个对象或者一个函数。我们先来看看对象的配置,也是最简单的配置方式,你可以在上述的示例项目中添加如下的 manualChunks 配置代码
// vite.config.ts
{
build: {
rollupOptions: {
output: {
// manualChunks 配置
manualChunks: {
// 将 React 相关库打包成单独的 chunk 中
'react-vendor': ['react', 'react-dom'],
// 将 Lodash 库的代码单独打包
'lodash': ['lodash-es'],
// 将组件库的代码打包
'library': ['antd', '@arco-design/web-react'],
},
},
}
},
}
在对象格式的配置中, key 代表 chunk 的名称, value 为一个字符串数组,每一项为第三方包的包名。
在进行了如上的配置之后,我们可以执行 npm run build 尝试一下打包:

原来的 vendor 大文件被拆分成了我们手动指定的几个小 chunk,每个chunk 大概 200 KB 左右,是一个比较理想的 chunk 体积。这样,当第三方包更新的时候,也只会更新其中一个 chunk 的 url,而不会全量更新,从而提高了第三方包产物的缓存命中率。
除了对象的配置方式之外,我们还可以通过函数进行更加灵活的配置。Rollup 会对每一个模块调用 manualChunks 函数,在 manualChunks 的函数入参中你可以拿到 模块 id 及 模块详情信息 ,经过一定的处理后返回 chunk 文件的名称 ,这样当前 id 代表的模块便会打包到你所指定的 chunk 文件中。我们现在来试着把刚才的拆包逻辑用函数来实现一遍:
manualChunks(id) {
if (id.includes('antd') || id.includes('@arco-design/web-react')) {
return 'library';
}
if (id.includes('lodash')) {
return 'lodash';
}
if (id.includes('react')) {
return 'react';
}
}
看上去好像各个第三方包的 chunk (如 lodash 、 react 等等)都能拆分出来,但实际上你可以运行 npx vite preview 预览产物,会发现产物根本没有办法运行起来,页面出现白屏,同时控制台出现如下的报错:

这也就是函数配置的坑点所在了,虽然灵活而方便,但稍不注意就陷入此类的产物错误问题当中。详细问题请查看原文:https://blog.csdn.net/Tyro_java/article/details/140050644
终极解决方案——vite-plugin-chunk-split插件
原文链接:https://blog.csdn.net/Tyro_java/article/details/140050644