esmodule 的静态导入为 tree shaking 提供前提,需满足具名导出/导入、禁止重赋值、避免 export *、正确配置打包工具并消除副作用才能生效。

ESModule 的静态导入本身不直接“实现”树摇优化,而是为 Tree Shaking 提供了必要前提——只有在满足特定条件时,打包工具(如 Webpack、Rollup、Vite)才能安全地剔除未使用的导出。
静态结构是基础
ESModule 的 import/export 语法在编译期就能确定依赖关系和导出成员,不像 CommonJS 的 require() 那样可能动态执行。这种静态可分析性让打包器能构建准确的依赖图,识别哪些 export 没被 import 过,从而标记为“可移除”。
- 必须使用 named export / named import(例如
export const foo = ...和import { foo } from './mod.js'),避免默认导出混用或重命名破坏引用链 - 禁止对导入的绑定重新赋值(
import { x } from './a.js'; x = 2;是非法的,也是 Tree Shaking 的保障之一) - 不要用
export * from './x.js'模糊导出,除非目标模块本身也支持 Tree Shaking;否则会阻断分析
打包配置需启用相关选项
即使代码符合 ESModule 规范,若打包工具未开启对应功能,也不会真正执行 Tree Shaking。
- Webpack:需设置
mode: 'production'(自动启用optimization.usedExports: true和concatenateModules: true) - Rollup:默认开启,但需确保
treeshake: true(默认即 true),且没有插件意外地将模块标记为“有副作用” - Vite:基于 Rollup 构建,开发时禁用 Tree Shaking(提升热更新速度),构建生产包时自动启用
避免副作用干扰判断
如果模块顶层存在执行逻辑(比如直接调用函数、修改全局变量、发起请求),打包器会认为它“有副作用”,不敢删除,哪怕它的导出没被用到。
- 把副作用逻辑移到函数内部(
export function init() { /* side effect here */ }),只在真正调用时触发 - 在
package.json中声明"sideEffects": false(表示整个包无副作用),或精确列出有副作用的文件(如["*.css", "src/init.js"]) - 避免在模块顶层写
console.log、localStorage.setItem等语句
常见失效场景与检查方式
Tree Shaking 失效往往不是语法问题,而是隐式引用或配置疏漏。
- 通过字符串拼接 import(
import(`./${name}.js`))属于动态导入,无法静态分析 - 使用了 Babel 转译但未关闭
modules: false(否则会把 ESModule 转成 CommonJS,破坏静态性) - 某些库的 UMD 或 IIFE 版本被意外引入(检查打包产物中是否含
function (global, factory)这类包裹) - 用
import * as mod from './x.js'会保留全部导出;改用具名导入或配合/*#__PURE__*/注释提示
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











