在 Rollup 中配置 Tree Shaking 主要通过以下步骤实现:
1. 使用 ES6 模块语法
确保项目中使用 import/export
而非 CommonJS(require/module.exports
)。Rollup 依赖静态结构分析来识别未使用的代码。
示例:
// 正确:ES6 模块语法
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
// 错误:CommonJS 语法(会破坏 Tree Shaking)
module.exports = {
add, subtract };
2. 配置 Rollup 插件
使用支持 Tree Shaking 的插件,如 @rollup/plugin-node-resolve
和 @rollup/plugin-commonjs
(处理 CommonJS 模块)。
示例配置(rollup.config.js
):
import {
nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {
terser } from 'rollup-plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es', // 使用 ES 模块格式以保留 Tree Shaking 能力
},
plugins: [
nodeResolve(), // 解析第三方模块
commonjs(), // 将 CommonJS 转换为 ES6
terser(), // 压缩代码,移除未使用的部分
],
};
3. 处理副作用(Side Effects)
在 package.json
中声明有副作用的文件,避免 Rollup 误删必要代码。
示例 package.json
:
{
"sideEffects": ["*.css", "src/init.js"]
}
4. 排除外部依赖
使用 external
选项排除不需要打包的依赖,减少包体积。
示例:
export default {
input: 'src/main.js',
output: {
format: 'es',
},
external: ['react', 'lodash'], // 不打包这些依赖
};
5. 使用正确的输出格式
优先选择 format: 'es'
(ES 模块)或 format: 'esm'
,避免使用 umd
或 iife
格式(可能导致 Tree Shaking 失效)。
示例:
export default {
output: {
format: 'es', // 推荐格式
},
};
6. 压缩代码
使用 terser
等压缩工具移除未使用的代码。
安装依赖:
npm install rollup-plugin-terser --save-dev
配置插件:
import {
terser } from 'rollup-plugin-terser';
export default {
plugins: [
terser({
compress: {
dead_code: true, // 移除未使用的代码
},
}),
],
};
7. 验证 Tree Shaking 效果
使用 source-map-explorer
分析打包结果,检查是否包含未使用的代码:
安装工具:
npm install -g source-map-explorer
生成并分析报告:
npx rollup -c --sourcemap
npx source-map-explorer dist/bundle.js
完整示例配置
// rollup.config.js
import {
nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import {
terser } from 'rollup-plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es',
sourcemap: true,
},
external: ['react', 'react-dom'], // 外部依赖不打包
plugins: [
nodeResolve(), // 解析第三方模块
commonjs(), // 处理 CommonJS 模块
babel({
// 转换 ES6+ 语法
babelHelpers: 'runtime',
exclude: 'node_modules/**',
}),
terser({
// 压缩并移除未使用代码
compress: {
dead_code: true,
},
}),
],
};
常见问题与解决方案
CommonJS 模块无法 Tree Shaking
- 解决方案:使用
@rollup/plugin-commonjs
转换为 ES6 模块。
- 解决方案:使用
CSS/样式被误删
- 解决方案:在
package.json
中声明样式文件有副作用:{ "sideEffects": ["*.css"] }
- 解决方案:在
Tree Shaking 未生效
- 检查是否使用了
format: 'es'
或format: 'esm'
。 - 确保未使用动态导入(如
import('./module').then(...)
)。
- 检查是否使用了
通过以上配置,Rollup 可以有效识别并移除未使用的代码,实现 Tree Shaking。