<p>Tree Shaking 未生效的核心原因是代码未以 ESM 方式被静态分析或导出引用链被中断:需确认 tsconfig 中 module 为 es2015/esnext、Babel 配置 modules: false、Webpack mode 为 production、package.json 正确声明 sideEffects,并避免动态导入、export * 等破坏静态分析的写法。</p>

排查 TypeScript 项目中 Webpack 的 Tree Shaking 未生效,核心是确认「代码是否以 ESM 方式被静态分析」以及「是否有因素中断了导出引用链」。不是所有 import 写法都能触发 Tree Shaking,尤其在 TS 编译和 Webpack 加载器协同环节容易出错。
检查 TypeScript 输出模块格式是否为 ES Module
Tree Shaking 依赖 ESM 的静态结构。若 tsconfig.json 中 "module" 设置为 "commonjs" 或 "umd",TS 编译后会生成 require 和 exports,Webpack 就无法做静态导出分析。
- 必须设为
"module": "es2015"、"es2020"或"esnext" - 同时确保
"target"不低于"es2015"(如"es2016"),避免因降级引入兼容性 wrapper - 验证编译产物:打开
dist或node_modules/.cache中实际生成的 JS 文件,确认含export/import语句,而非module.exports
确认 Babel 是否意外转译了 ES 模块
即使 TS 输出 ESM,若后续经 babel-loader 处理且未禁用模块转换,Babel 会把 import/export 转成 require/module.exports,直接关闭 Tree Shaking。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 在
.babelrc或babel.config.js中,@babel/preset-env必须配置modules: false - 错误示例:
{"presets": ["@babel/preset-env"]}(默认开启modules: "commonjs") - 正确示例:
{"presets": [["@babel/preset-env", {"modules": false}]]} - 可临时移除 Babel 验证:注释掉
babel-loader规则,仅用ts-loader,再观察体积变化
验证 Webpack 生产模式与副作用声明
Tree Shaking 在 Webpack 中默认仅在 mode: "production" 下启用,且需配合明确的副作用控制策略。
- 确保
webpack.config.js中mode: "production"(开发模式下不启用) - 检查项目根目录
package.json是否声明"sideEffects": false;若项目中有 CSS、JSON 或有副作用的 JS(如 polyfill),需显式列出,例如:"sideEffects": ["*.css", "*.scss"] - 第三方库(如
date-fns)若未正确声明sideEffects,其子模块(如locale)可能全量保留——此时应改用深层路径导入:import zhCN from "date-fns/locale/zh-CN",绕过聚合入口
识别间接引用与动态语法干扰
ESM 静态分析对“非确定性”语法极为敏感,任何运行时才能判定的引用都会让工具保守保留全部导出。
- 避免在模块顶层使用
eval()、with、arguments等破坏静态分析的语法 - 禁止动态
import()导入模块后解构使用(如import('./utils').then(m => m.helper())),这无法被 Tree Shaking 分析 - 慎用
export * from 'xxx':它会透传所有导出,即使只用其中一两个,Webpack 也难以安全剔除其余项 - 检查是否存在命名重导出但别名未被识别的情况,例如
export { foo as bar },而代码中只用了bar—— 某些旧版 Webpack 可能未建立别名映射

















