Tree Shaking 依赖打包工具对 ES 模块的静态分析,需在 package.json 中通过 "exports" 字段(优先设 "import")或 "type": "module" 正确声明 ESM 入口;避免仅用 "main" 或已弃用的 "module" 字段,否则将导致摇树失效。

Tree Shaking 不是通过 package.json 配置实现的,而是由打包工具(如 Webpack、Vite、Rollup)在构建时,基于 ES 模块的静态结构分析,自动剔除未使用的导出(exports)。但 package.json 中的某些字段会影响 Tree Shaking 是否生效,关键在于**正确声明模块入口**,让打包工具能识别你发布的代码是 ES Module 格式。
✅ 必须设置 "type": "module" 或提供 "exports" 字段
如果你的包本身是用 ES 模块(.js 文件含 export/import)编写的,并希望使用者能正常 Tree Shake,需明确告诉工具:“这个包的默认入口支持静态分析”:
- 推荐方式:使用
"exports"字段精确声明不同环境下的入口,且优先指定"import"字段指向 ESM 文件(如"./dist/index.js") - 兼容方式:若整个包是纯 ESM,可在根目录
package.json中写"type": "module"(注意这会要求所有.js文件按 ESM 解析,可能影响 CommonJS 用户)
⚠️ 避免覆盖或误导的字段
以下字段若配置不当,会破坏 Tree Shaking:
-
"main"指向一个 UMD 或 CommonJS 打包产物(如index.cjs)→ 打包工具无法静态分析,Tree Shaking 失效 -
"module"字段虽曾被 Webpack 支持,但它是非标准字段,已被现代工具(如 Vite、Rollup)逐步弃用;依赖它不如用标准"exports" - 未声明
"exports",仅靠"main"和"module"→ 工具可能 fallback 到 CommonJS 入口,失去摇树能力
? 示例:推荐的 package.json 片段
假设你构建后输出了 ESM 格式的 dist/index.js 和 CJS 格式的 dist/index.cjs:
立即学习“Java免费学习笔记(深入)”;
{
"name": "my-lib",
"type": "commonjs",
"main": "./dist/index.cjs",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"types": "./dist/index.d.ts"
}
这样配置后,当用户用 import { foo } from 'my-lib' 时,Vite/Webpack(v5+)会优先解析 "import" 入口,启用 Tree Shaking;而 require('my-lib') 仍可工作。
? 补充提醒
- 你的源码必须用
export/import(不是module.exports),否则即使入口是 ESM,也没有可摇的“树” - 确保构建工具(如 Rollup/Vite)输出的是真正的 ESM(
format: 'es'),而不是带__esModule的模拟模块 - 用户项目里也要开启生产模式(
mode: 'production')和optimization.usedExports: true(Webpack)等配合选项


















