tree shaking 是一种基于 es 模块静态分析的死代码消除技术,通过构建工具建立依赖图、标记已引用导出、剔除未使用代码来减小打包体积;需满足使用 import/export、生产模式、无副作用、babel 保留 esm 等前提。

要让公共工具函数库在 Tree Shaking 中被高效剔除未使用部分,关键不是“写得少”,而是“导出得细、结构得清、副作用得净”。只要模块结构符合静态分析要求,构建工具就能准确识别哪些函数真正被用到。
按粒度导出每个独立函数
避免把多个工具函数打包进一个对象或默认导出里。聚合式导出会让整个对象被整体保留,哪怕只调用其中一两个方法。
-
❌ 不推荐:
export const utils = { debounce, throttle, deepClone };—— 只用了debounce,但throttle和deepClone仍会留在包中 -
✅ 推荐:
export const debounce = ...;export const throttle = ...;export const deepClone = ...;—— 每个函数单独导出,可被独立标记和移除
禁用默认导出与命名空间式引入
默认导出(export default)和通配符导入(import * as xxx)会阻断静态分析路径,导致整个模块无法被摇掉。
-
❌ 避免:
import Utils from 'my-utils'; Utils.debounce(...) -
✅ 坚持:
import { debounce } from 'my-utils';—— 明确声明依赖项,构建工具才能精准追踪引用链 - 若必须提供默认导出,确保它只是具名导出的重命名(如
export { debounce as default }),而非新对象包装
声明无副作用并配置 package.json
即使函数本身没副作用,模块顶层执行语句(如日志、全局变量赋值、DOM 操作)也会让构建工具保守处理,放弃摇树。
-
清理顶层代码: 工具库入口文件(如
index.js)只做导出,不执行任何逻辑 -
显式声明: 在
package.json中添加"sideEffects": false,告诉 Webpack/Vite:本库所有文件都无副作用,可安全剔除未引用部分 -
例外处理: 若某些文件确实有副作用(如 CSS 导入、polyfill 注入),用数组列出路径:
"sideEffects": ["./dist/style.css", "*.css"]
确保构建流程不破坏 ES 模块结构
Babel 等转译器若将 import/export 转为 require/exports,Tree Shaking 就彻底失效。
-
Babel 配置中必须设:
{ "modules": false },保留原生 ESM 语法 -
第三方库注意: 使用已发布 ESM 版本的库(如 lodash-es 而非 lodash),或通过别名强制指向其
module字段入口 -
Vite/Webpack 生产模式启用:
mode: 'production'是触发 Tree Shaking 的前提,开发模式下通常关闭该优化











