Tree Shaking 是 Webpack 5+ 通过静态分析 ES 模块 import/export 删除未引用代码以减小包体积的技术,要求使用 ES 模块、避免动态导入、正确配置 sideEffects 并按需引入。

Tree Shaking 是 Webpack 5+(及支持 ES 模块的打包工具)在构建时静态分析代码,自动剔除未被引用的导出(export)和导入(import)语句,从而减小最终包体积的技术。它只对 ES6 模块语法(import/export)生效,不适用于 CommonJS(require/module.exports)。
确保使用 ES 模块语法
Tree Shaking 的前提是模块必须是静态可分析的。ES 模块的 import 和 export 在编译期就确定了依赖关系,而 CommonJS 是运行时动态加载,无法安全判断哪些导出没被用到。
- ✅ 正确(可被 shake):
import { foo } from './utils.js'; export const bar = () => {}; - ❌ 无法 shake:
const utils = require('./utils'); module.exports = { bar: () => {} }; - ⚠️ 注意:即使用了
import,如果做了动态导入(import('./xxx.js'))或通过变量拼接路径,也会绕过 Tree Shaking。
避免副作用干扰(sideEffects)
Webpack 默认认为所有模块都有副作用(比如执行全局逻辑、修改原型、打日志等),为安全起见不会删掉看似“未使用”的模块。你需要显式声明哪些文件没有副作用,才能让它们被安全移除。
- 在
package.json中添加:"sideEffects": false(表示整个包无副作用,谨慎使用) - 或更精确地写:
"sideEffects": ["*.css", "*.scss"](仅保留 CSS 等有副作用的文件,JS 文件默认可 shake) - 若某个 JS 文件确实只做副作用(如 polyfill),可在文件顶部加注释:
/*#__PURE__*/标记单个调用,或用/* webpackExports: ["init"] */等方式辅助分析(较少用)
按需引入,避免整包导入
即使模块支持 Tree Shaking,错误的引入方式仍会导致大量无用代码进入打包结果。
立即学习“Java免费学习笔记(深入)”;
- ❌ 避免:
import _ from 'lodash';(引入全部方法,即使只用_.debounce) - ✅ 推荐:
import debounce from 'lodash/debounce';或import { debounce } from 'lodash-es';(lodash-es是专为 Tree Shaking 优化的版本) - ✅ 组件库也同理:用
import Button from 'antd/es/button';而非import { Button } from 'antd';(前提是你已配置 Babel 插件或使用支持 ESM 的版本)
检查打包结果确认是否生效
光写对语法还不够,得验证 Tree Shaking 是否真实起效。
- 启用 Webpack 的
stats: "verbose"或使用webpack-bundle-analyzer可视化分析产物 - 在源码中故意导出一个未使用的函数,再看最终 bundle 里是否存在该函数代码(搜索函数名或字符串)
- 注意:开发模式下常关闭压缩和优化,务必在
mode: 'production'下测试,且确保optimization.usedExports: true(Webpack 5 默认开启)


















