tree shaking 能在构建时自动剔除未被引用的工具函数,前提是代码使用 es module 规范、无副作用干扰、按需导入且正确声明 sideeffects。

Tree Shaking 能在构建时自动剔除未被引用的工具函数,但前提是代码必须满足 ES Module(ESM)规范,且不能有副作用干扰静态分析。核心不是“怎么写 Tree Shaking”,而是“怎么写能让 Webpack/Vite 等打包工具安全地摇掉无用代码”。
确保工具模块用 ES Module 导出
CommonJS(module.exports / require)无法被静态分析,Tree Shaking 会失效。所有业务工具函数必须用 export 显式导出,调用方用 import 按需引入。
✅ 正确写法(支持摇树):
// utils/date.js export const formatDate = (date) => new Date(date).toLocaleString(); export const isToday = (date) => new Date().toDateString() === new Date(date).toDateString(); export const parseISO = (str) => new Date(str); // 这个如果没被 import,会被摇掉
❌ 错误写法(无法摇树):
// utils/date.js(CommonJS)
module.exports = {
formatDate: (date) => ...,
isToday: (date) => ...,
parseISO: (str) => ...
};
避免副作用干扰静态分析
即使用了 ESM,如果模块顶层有执行逻辑(比如直接调用函数、修改全局变量、触发 console 或 API 请求),打包工具会认为它有副作用,不敢轻易移除——哪怕你一个函数都没 import。
- 把初始化、监听、打点等逻辑移到函数内部,而非模块顶层
- 在
package.json中显式声明"sideEffects": false(表示整个包无副作用),或列出有副作用的文件(如["*.css", "index.js"]) - 避免在工具模块里直接
localStorage.setItem、console.log、new Audio()等
按需导入,别用 namespace import
使用 import * as utils from './utils' 或 import utils from './utils'(默认导出)会让打包器难以判断哪些成员被真正使用,大概率保留全部导出。
- ✅ 推荐:
import { formatDate, isToday } from './utils/date' - ⚠️ 避免:
import * as dateUtils from './utils/date'(除非配合/*#__PURE__*/注释且确认只用其中一两个) - ? 小技巧:Vite/Webpack 默认开启
usedExports,但若你用了 Babel,要关掉@babel/preset-env的modules: 'commonjs',否则会把 ESM 编译成 require,破坏摇树
验证是否真的被摇掉
别只信配置,要用工具看结果:
- Webpack:加
--stats=verbose构建后搜unused exports;或用source-map-explorer可视化包体积 - Vite:运行
vite build --report生成report.html,查看各模块是否标记为unused - 关键检查点:打开最终打包产物(如
dist/assets/index.xxxx.js),搜索你确定没引用的函数名,确认不存在
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











