tree shaking 是需代码写法、构建配置、依赖管理协同的系统实践,核心是保障“可静态分析”:模块须用 es module、禁用命名空间导入、精准匹配导出导入、真实声明副作用,并通过产物验证效果。

Tree Shaking 不是配置开关一开就自动瘦身的魔法,而是需要代码写法、构建配置、依赖管理三者对齐的系统性实践。制定有效策略的关键,在于抓住“可静态分析”这个核心——所有优化动作都围绕让打包工具能准确识别“哪些导出真没被用”来展开。
确保模块系统干净可用
这是整个优化的地基,不满足则后续全部失效。
- 项目内所有自定义模块必须使用 ES Module 语法:统一用
export function xxx、export const yyy,禁用module.exports = {}或export default { a, b }这类对象式导出 - 检查 Babel 配置:若使用
@babel/preset-env,必须设modules: false,防止import被转译成require - 第三方库优先选原生 ESM 版本:例如用
lodash-es替代lodash,用date-fns替代moment;组件库如 Ant Design 推荐配合babel-plugin-import或直接导入子路径(import Button from '@ant-design/react-button')
导入导出方式要精准匹配
写法不对,再好的配置也白搭。Webpack 的摇树判断高度依赖 import 的静态结构。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 禁止命名空间导入:
import * as utils from './utils'会让整个模块被视为“已使用”,无法剔除未调用函数 - 坚持具名导入:
import { debounce, throttle } from 'lodash-es',让工具能逐个标记导出项 - 避免默认导入整包:
import _ from 'lodash-es'改为按需路径导入:import debounce from 'lodash-es/debounce' - 类库作者注意:不要把多个工具函数塞进一个
export default { ... }对象里,应每个函数独立export const xxx
副作用声明必须真实且精确
Webpack 发现模块有副作用(比如改 window、注入 CSS、执行 polyfill),就会保守保留整文件——哪怕你只用了其中一行代码。
- 在项目根目录
package.json中添加:"sideEffects": false(表示所有源文件无副作用) - 若有真实副作用,必须显式列出文件:
"sideEffects": ["./src/polyfill.js", "./styles/index.css", "*.scss"] - 把副作用逻辑从工具模块中移出:例如
import './reset.css'不要放在utils/index.js顶层,而应移到入口文件或具体组件中 - 避免在模块顶层调用函数、发请求、监听事件等实际执行行为
验证效果不能靠猜测
配置写了≠生效了。必须通过产物反向确认是否真正摇掉代码。
- 构建时启用详细统计:
webpack --stats=verbose,搜索unused harmony export看目标函数是否被标记 - 用
source-map-explorer或webpack-bundle-analyzer可视化分析 bundle 构成,定位大模块中哪些子项仍存在 - 做对照实验:临时加一行
import { unusedHelper } from './helpers',再构建看体积是否增加;若没变化,说明该导出已被成功摇掉 - 打开最终 JS 文件,手动搜索未使用函数名或类名,确认其代码体是否还存在










