tree shaking 依赖 es modules 的静态结构特性,需使用静态 import/export、避免顶层副作用、配置 sideeffects、构建输出为 esm 格式,并在 package.json 中正确声明 esm 入口。

Tree Shaking 要真正起作用,必须依赖 ES Modules(ESM)的静态结构特性。它不是一种独立功能,而是构建工具对 ESM 代码做静态分析后自然产生的优化结果。
ES Modules 是 Tree Shaking 的前提
只有 ESM 的 import/export 语句是静态的:路径、绑定名、导出项在解析阶段就能确定,不随运行时条件变化。打包工具(如 Rollup、Webpack、Vite)正是靠这个特性,在构建时扫描 AST,生成模块依赖图,再从入口开始追踪哪些导出被实际引用。
- ✅ 正确示例:import { debounce } from './utils.js'; export const throttle = () => {};
- ❌ CommonJS 不行:const { debounce } = require('./utils'); —— 运行时才能知道导入了什么,无法静态判定是否使用
- ❌ 动态 import() 不参与分析:import(`./feature-${type}.js`) —— 路径不确定,工具跳过该分支的依赖追踪
只用 ESM 语法还不够:避免副作用干扰
即使全是 export/import,如果模块顶层有可观察的执行逻辑(比如直接调用函数、修改全局变量、添加事件监听),打包工具会认为它“有副作用”,为安全起见,不会删除整个模块——哪怕其中大部分导出都没被用到。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ? 避免这样写:console.log('utils loaded'); globalThis.utilsReady = true;
- ✅ 推荐写法:模块只做声明和导出,副作用逻辑封装成函数,由用户显式调用
- ? 补充手段:在 package.json 中设置 "sideEffects": false(表示全项目无副作用),或精确列出有副作用的文件,如 "sideEffects": ["*.css", "index.js"]
构建配置需配合 ESM 流程
工具链必须保留 ESM 结构并启用压缩,否则静态分析的结果不会落地为体积减少。
- 输出格式选 es 或 esm(Rollup/Vite 默认;Webpack 需设 output.format = 'es')
- Webpack 必须开启 mode: 'production',或手动启用 optimization.usedExports: true 和 minimize: true
- 确保 TypeScript 编译目标为 module: "esnext",而非 commonjs,否则生成的 JS 仍会是 require 形式
库作者还要暴露 ESM 入口
如果你发布的是 npm 包,使用者能否摇树,取决于你是否提供了清晰的 ESM 路径。
- 在 package.json 中声明:
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"exports": { ".": { "import": "./dist/index.esm.js", "require": "./dist/index.cjs.js" } } - 这样 Webpack/Rollup 等工具才能优先加载 ESM 版本,启动静态分析流程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










