Babel配置会影响Tree Shaking效果吗?

长孙淑宁 阅读 43

我最近在优化项目打包体积,发现即使用了ES Module,Webpack的Tree Shaking好像也没生效。我怀疑是不是Babel的配置有问题,因为看到有人说Babel会把import/export转成CommonJS,导致Tree Shaking失效。

我现在的Babel配置里用了@babel/preset-env,但没特别设置modules选项。比如下面这段代码,明明只用了add,但打包后subtract也被包含进去了:

// utils.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// index.js
import { add } from './utils';
console.log(add(1, 2));

是不是要加什么配置才能让Babel保留ES Module语法,不破坏Tree Shaking?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
程序员丹丹
你猜得没错,Babel的配置确实会影响Tree Shaking效果,问题就出在 @babel/preset-env 默认把ES Module转成了CommonJS,Webpack就无法做静态分析了。

默认情况下,modules 选项是 "auto",在Webpack环境下它会自动转成CommonJS,这就把import/export全换成require了,Tree Shaking自然就失效了。

解决办法很简单,在Babel配置里显式关掉模块转换:

{
"presets": [
["@babel/preset-env", {
"modules": false
}]
]
}


或者如果你用的是 .babelrc.jsbabel.config.js,写法类似:

module.exports = {
presets: [
['@babel/preset-env', { modules: false }]
]
};


这样Babel就不会动你的import/export了,Webpack就能正常做Tree Shaking。

不过要注意,关掉modules转换后,Babel就不会处理模块语法了,但其他特性(比如async/await、class属性等)还是会正常转译,只要你的targets配置合理就行。

另外提醒一句,Webpack 4默认开启Tree Shaking的前提是 mode 设为 production,或者手动配置 optimization.usedExports = true,确认下你的Webpack配置里没漏掉这个。

更好的写法是把Babel和Webpack的配置都统一管理,避免这种隐式坑,比如用 babel-loader 时加上 presets: [['@babel/preset-env', { modules: false }]],这样一目了然,也不容易忘。
点赞 2
2026-02-24 21:11