tree shaking 在混用 commonjs 会失效,因 commonjs 是运行时动态加载,无法静态分析导出内容;esm 的 import 语法明确依赖,而 commonjs 的 require 和动态属性访问使推断不可行。 tree shaking 在混用commonjs(require/module.exports)时会直接失效,因为 commonjs 是运行时动态加载,无法静态分析导出内容。rollup、iooo

JS 中 Babel 转换配置不当会直接破坏 ES Modules 的静态结构,让 Tree Shaking 彻底失效——不是“效果不好”,而是根本无法启动。
把 import/export 转成 require/module.exports
这是最常见、最致命的问题。Babel 默认启用 @babel/preset-env,而它的 modules 选项在未显式设为 false 时,会把所有 ES 模块语法转成 CommonJS:
-
import { foo } from './utils'→const utils = require('./utils'); const foo = utils.foo -
export function foo() {}→exports.foo = function foo() {}
一旦变成 require 和 exports,模块就失去静态可分析性。打包工具(Webpack/Rollup)再也无法判断哪些导出没被引用,只能保守保留全部代码。
错误启用 @babel/plugin-transform-modules-commonjs
即使你手动写了 ES 模块,这个插件也会强行“降级”:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 它会把本该保留的
export const bar = 1编译成module.exports.bar = 1 - 命名导入
import { bar } from './utils'变成运行时属性访问,Tree Shaking 完全失效 - 尤其在搭配 Webpack 4+ 时,该插件与内置的模块解析逻辑冲突,导致
usedExports标记失败
混用默认导出对象 + 解构导入
这类写法本身不合规,Babel 还可能“帮忙圆场”,进一步掩盖问题:
- 源码:
export default { a: 1, b: 2 }+import { a } from './lib' - Babel 5 曾错误支持这种解构,默认导出对象被当作命名导出处理,看似能用,实则破坏模块语义
- Babel 6+ 已修复,但若项目残留兼容插件(如
babel-plugin-add-module-exports),仍会维持错误行为,导致摇树无法识别真实引用关系
未关闭 modules 转换,却依赖 ESM 生态
当你使用 lodash-es 或 @carbon/icons-react 这类原生 ESM 库时,Babel 的转换反而成了绊脚石:
- 库内部是
export function debounce(),但 Babel 把它转成exports.debounce = - 你的
import { debounce } from 'lodash-es'变成动态取值,整个模块被当做一个黑盒保留 - 结果:明明用了按需导入,打包后体积却和全量引入一样
解决方法很简单:在 .babelrc 或 babel.config.js 中明确设置
并确保不额外引入任何模块转换插件。让 ES 模块原样透传给 Webpack/Rollup,它们才能真正执行静态分析。










