lodash-es 按需引入后为什么打包体积还是很大?
我用的是 Vite + Vue3,想通过 tree shaking 减小 lodash 的打包体积,就改用了 lodash-es,并只 import 了 debounce。但 build 完发现 vendor chunk 还是很大,好像整个 lodash 都被打进来了?
我试过这样写:
import { debounce } from 'lodash-es';
const debouncedFn = debounce(() => {
console.log('resize');
}, 300);
也确认 vite.config.js 里没关掉 tree shaking,但分析 bundle 发现 lodash-es 占了快 70KB。是不是我哪里写错了?
关键问题是lodash-es的模块导出方式。虽然我们只用了debounce,但因为lodash内部的依赖关系,很多基础工具函数会被连带打包进来。解决方案有两个:
1. 更彻底的按需引入写法:
这样直接从子路径引入,可以避免引入整个lodash的模块系统。
2. 如果还是觉得大,可以考虑换成更轻量的方案,比如:
或者直接用自己实现的debounce函数(对于简单场景足够了)。
最后检查下你的打包分析工具,70KB对于单个debounce确实有点大,但lodash的基础工具函数加起来差不多这个体积,可能已经是最佳状态了。如果还嫌大,那就只能自己手写debounce了。
如果确定只用lodash-es,试试这样改导入方式:
直接走具体模块路径而不是从主入口导入,这样webpack/vite会更明确地只打包这一个函数。
另外建议跑下
npx vite-bundle-visualizer看看具体是哪些模块被打进来了,有时候你以为的"整个lodash"其实只是lodash的一些核心依赖。还有种可能是你的debounce函数被多处引用导致看起来体积大,但其实是被压缩合并过的。70KB确实有点夸张,正常单函数应该在10KB以内。
最后终极方案:如果还不行,直接换
lodash.debounce这个独立包吧,专治各种tree shaking不灵。