Tree Shaking 为什么没生效?按需引入 lodash 还是打包了整个库?
我用的是 webpack5 + babel,想按需引入 lodash 的 debounce 方法,但打包后发现整个 lodash 库都被打进去了,体积一点没减。
我试过直接 import { debounce } from 'lodash',也试过装 babel-plugin-lodash 插件,但都没效果。是不是我配置哪里错了?
这是我的 webpack 配置相关部分:
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
},
// ...其他配置
}
你配置的
usedExports和sideEffects都没问题,但 Tree Shaking 的前提是模块必须是 ES Module 格式,静态分析才能识别哪些导出被用到了。CommonJS 是动态加载的,webpack 没法在编译时确定,只能全量打包。解决方案有两个,推荐第一个。
方案一:换成 lodash-es
lodash-es 是官方提供的 ES Module 版本,配合你的配置,Tree Shaking 宔美生效。记得把 babel-plugin-lodash 卸了,用 lodash-es 不需要这玩意儿。
方案二:路径引入
这种方式直接引入具体文件,不经过模块解析,自然也不会打包整个库。缺点就是写法麻烦,引入多个方法的时候要写一堆。
另外说一句,babel-plugin-lodash 要生效的话,你得确保 babel 配置正确加载了这个插件,而且它主要是处理路径转换的,本质上还是方案二的思路。但前端这块我建议直接用 lodash-es,省心。
还有个小坑,如果你用了 @babel/preset-env 并且开启了 modules 转换,会把 ES Module 编译成 CommonJS,Tree Shaking 又废了。配置里得加上:
这样 ES Module 就能保留原样,webpack 才能做 Tree Shaking。