webpack 自 v2 起原生支持 tree shaking,需使用 es 模块语法、设 tsconfig.json 的 "module": "esnext"、用 lodash-es 等 esm 库、配置 optimization.usedexports 和 minimize、正确声明 sideeffects,避免动态导入等破坏静态分析的行为。

Webpack 本身不“配置 Rollup 风格的 Tree Shaking”,因为 Tree Shaking 不是 Rollup 独有的风格,而是基于 ES 模块静态结构的标准行为。Webpack 自 v2 起就原生支持 Tree Shaking,只要满足前提条件,效果和 Rollup 一致——关键不是模仿 Rollup,而是让 Webpack 正确启用并发挥其内置能力。
确保使用 ES 模块语法
Tree Shaking 的基础是静态可分析的 import/export。如果代码里混用 require 或 Babel 转译成 CommonJS,就会中断分析链。
- TS 编译选项必须设为
"module": "esnext"(不能是commonjs或amd) - 避免在业务代码中写
import * as _ from 'lodash'这类全量导入 - 第三方库要选 ESM 版本,例如用
lodash-es替代lodash,用rxjs/operators替代rxjs/Rx
开启 Webpack 的摇树相关开关
Webpack 默认在 mode: "production" 下启用 Tree Shaking,但显式配置更稳妥、更可控:
- 设置
optimization.usedExports: true:标记哪些导出被使用,为后续剔除提供依据 - 启用
optimization.minimize: true(生产模式默认开启),配合 TerserPlugin 才能真正移除未引用代码 - 确认
experiments.topLevelAwait: false(保持默认即可),避免破坏静态分析
正确声明副作用
Webpack 需要知道哪些文件“除了导出之外还有其他影响”,否则可能误删有副作用的模块(如全局样式注入、polyfill)。
- 在
package.json中添加"sideEffects"字段 - 值为
false表示整个包无副作用,可安全摇树 - 值为
["*.css", "*.scss"]表示仅这些资源有副作用,其余 JS 文件可放心分析 - 若入口文件或工具函数中有
localStorage.setItem、console.log等,不属于副作用,无需额外标注
避免破坏静态分析的行为
以下写法会让 Webpack(或 Rollup)无法判断导出是否被使用,导致 Tree Shaking 失效:
- 动态导入:
import(moduleName)—— 改用静态命名导入 + 条件逻辑 - 通过字符串拼接构造模块路径:
import(`./${name}.ts`) - 把
export写在非顶层作用域(如if块内) - 使用
export default时,若接收方用import * as ns,部分场景下可能绕过分析
不需要引入 Rollup,也不需要“模拟 Rollup”。按 Webpack 官方推荐方式组织代码、配置 tsconfig.json 和 webpack.config.js,就能获得和 Rollup 同等质量的 Tree Shaking 效果。










