Webpack 4中搭配babel-loader时Tree Shaking功能失效问题
我之前也踩过一模一样的坑!加了babel-loader之后Tree Shaking突然罢工,折腾了好半天才搞懂问题出在哪——Babel默认会把ES模块语法转换成CommonJS,而Webpack的Tree Shaking核心依赖ES模块的静态分析能力,CommonJS是动态加载的,Webpack根本没法判断哪些代码没被用到。
给你几个关键的修复步骤,亲测有效:
1. 让Babel保留ES模块语法
修改你的Babel配置(不管是babel.config.js还是.babelrc),给@babel/preset-env加上modules: false或者modules: "auto"(Webpack 5+更推荐auto,它会自动检测打包工具并保留ES模块):
{ "presets": [ ["@babel/preset-env", { "modules": false, "targets": "> 0.25%, not dead" }] ] }
这样Babel就不会把import/export转成require/module.exports,Webpack就能正常做静态分析了。
2. 确保Webpack运行在production模式
Tree Shaking在development模式下默认是关闭的,Webpack为了方便调试会保留所有代码。所以一定要在webpack.config.js里把mode设为production:
module.exports = { mode: 'production', entry: './index.js', output: { filename: 'bundle.js', path: __dirname + '/dist' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' } ] } };
3. 配置package.json的sideEffects字段(可选但推荐)
这个字段用来告诉Webpack哪些文件有“副作用”(比如全局样式、修改全局变量的代码),不需要做Tree Shaking。如果你的math.js和其他业务代码没有副作用,直接在package.json里加:
{ "sideEffects": false }
如果有带副作用的文件(比如.css),就列出来:
{ "sideEffects": ["*.css"] }
做完这些配置后,重新打包,你会发现bundle里已经没有未被使用的square函数代码了,Tree Shaking就正常工作啦!
内容的提问来源于stack exchange,提问作者Zhengquan Bai

