【工程化】tree-shaking 的作用以及配置
Tree Shaking(摇树优化)是构建工具(如 Webpack、Rollup、Vite)中用于移除未使用代码,能显著减小打包体积。
⚙️ 一、基础配置条件
-
使用 ES Module (ESM) 语法
-
必须使用
import/export
,禁用 CommonJS(如require/module.exports
)。 -
正确示例:
// 按需导入(支持 Tree Shaking) import { debounce } from 'lodash-es';
// 错误示例(全量导入,无法优化) import _ from 'lodash';
-
-
启用生产模式
Webpack/Vite 在生产模式(mode: 'production'
)下默认开启 Tree Shaking 和代码压缩。// webpack.config.js module.exports = {mode: 'production', // 关键配置optimization: {usedExports: true, // 标记未使用导出minimize: true, // 启用压缩(删除死代码)}, };
📦 二、关键配置步骤
1. 配置 sideEffects
属性(核心)
在项目的 package.json
中声明文件副作用,指导构建工具安全删除未使用代码:
{"name": "your-project","sideEffects": false, // 所有文件无副作用(可安全删除)// 或指定有副作用的文件(如 CSS、全局 JS)"sideEffects": ["*.css", // 避免 CSS 被误删"src/polyfills.js" // 如 Babel polyfill]
}
2. Babel 配置:避免破坏 ESM 结构
确保 Babel 不将 ESM 转为 CommonJS(默认行为会破坏 Tree Shaking):
// .babelrc
{"presets": [["@babel/preset-env", { "modules": false // 保留 ESM 语法}]]
}
3. 第三方库的优化引入
-
优先选择 ESM 版本:如
lodash-es
替代lodash
。 -
按需导入子模块:
import debounce from 'lodash/debounce'; // 直接引入子文件
⚠️ 三、常见问题与解决方案
1. Tree Shaking 失效场景
原因 | 解决方案 |
---|---|
使用 CommonJS 语法 | 全项目统一改用 ESM 语法 |
未正确配置 sideEffects | 在 package.json 中标记副作用文件(如 CSS) |
Babel 转换破坏 ESM | 设置 "modules": false |
导出方式不当 | 避免 export default 对象,改用命名导出(Named Exports) |
2. CSS 等资源被误删
通过 sideEffects
标记或 Webpack 规则排除:
// webpack.config.js
module: {rules: [{test: /.css$/,use: ['style-loader', 'css-loader'],sideEffects: true // 声明 CSS 有副作用}]
}
3. 开发环境调试优化
开发模式下 Tree Shaking 仅标记未使用代码(不删除),避免破坏 SourceMap:
mode: 'development',
optimization: {usedExports: true, // 标记未使用导出(可查看日志)minimize: false // 关闭压缩
}
🛠️ 四、构建工具差异
工具 | 配置要点 |
---|---|
Webpack | 需手动开启 usedExports + minimize ,依赖 sideEffects 标记 |
Rollup | 默认支持 Tree Shaking,无需额外配置 |
Vite | 生产模式自动启用(基于 Rollup) |
💎 总结:最佳实践
-
代码规范:全项目使用 ESM 语法,避免
export default
对象。 -
构建配置:
- Webpack:
mode: 'production'
+usedExports: true
+minimize: true
。 package.json
中声明sideEffects
。
- Webpack:
-
三方库:优先选择 ESM 版本,按需引入子模块。