Vite预构建后依赖包体积反而变大了怎么办?
我在项目里给某个第三方库用了vite optimizeDeps预构建,结果打包后的vendor.js比之前还大200kb,这是怎么回事?
之前配置是这样的:
optimizeDeps: {
entries: ['index.html'],
exclude: ['vue-demi'],
include: ['lodash'],
// 添加了预构建配置
}
尝试过删除node_modules和dist重新构建,还是没变化。用vite inspect看依赖图发现lodash被拆成了多个独立块,但其他未预构建的库反而合并得更好。是不是预构建参数设置有问题?
include: ['lodash']其实有点问题——lodash 本身是模块化导出的(比如import _ from 'lodash'或import debounce from 'lodash/debounce'),但预构建会把它打包成一个整体 UMD 或 ESM 文件,反而把本来可以 tree-shaking 的部分“固化”了。Vite 的 optimizeDeps 更适合那些本身没有良好 ESM 分包、或者依赖链深且静态分析困难的库(比如 old-school 的 jQuery 插件、某些打包不规范的包),而不是 lodash 这种本身就支持 tree-shaking 的库。
我的做法是先检查你项目里怎么用 lodash 的——如果只是用几个函数,比如
import debounce from 'lodash/debounce',那根本不需要预构建,Vite 默认就能 tree-shaking;只有当你用的是import _ from 'lodash'这种全量引入时,才可能需要预构建,但这时候你得配合lodash-es或者用babel-plugin-lodash来避免全量引入。另外你看到 vendor.js 被拆成多个块,很可能是因为 Vite 把 lodash 预构建后生成了
.vite/deps/lodash.js这样的缓存,但你的业务代码里其实没完全命中这个缓存(比如动态 import、条件引用),反而导致重复加载。建议先删掉
include: ['lodash'],然后运行vite --force清掉预构建缓存再试一次。如果确实有性能问题,用npm run build -- --report看具体是谁占了体积——我之前遇到过 lodash-es 被重复打包两次的情况,一次是直接依赖,一次是间接依赖,这种得用resolve.alias或optimizeDeps.include显式指定统一入口。还有个小坑:如果你用了
optimizeDeps.exclude: ['vue-demi'],但没加vue-demi到 include,它不会被预构建,但 lodash 如果被它间接引用,也可能导致重复打包。总之预构建不是“加了就快”,它更像一种“强制提前绑定”的手段,用不好反而会变重。原因是你之前把
lodash单独拎出来预构建了,结果它被拆成了小块。去掉手动指定的include,让 Vite 自己判断哪些需要预构建,同时用manualChunks强制合并第三方库。再跑一次
vite build看看,应该能解决问题。如果还不行,可能就是那个第三方库本身的问题了,得换个库或者找作者反馈。