在 Vite 中配置 Tree Shaking 可以通过以下步骤实现,以确保最佳效果:
1. 使用 ES 模块语法
确保项目中使用 ES6+ 模块语法(import/export
)而非 CommonJS(require
)。Vite 基于 ES 模块的静态结构分析实现 Tree Shaking。
错误示例:
// CommonJS 语法(不支持 Tree Shaking)
const utils = require('./utils');
正确示例:
// ES 模块语法
import {
utils } from './utils';
2. 配置 package.json
的 sideEffects
明确标记有副作用的文件,避免 Vite 误删必要代码。
示例配置:
{
"sideEffects": [
"*.css", // CSS 文件有副作用
"*.scss", // SCSS 文件有副作用
"src/setup.js", // 自定义初始化脚本
"node_modules/**" // 第三方库默认有副作用(可细化)
]
}
最佳实践:
- 优先标记具体文件,避免使用通配符(如
"sideEffects": false
)。 - 对第三方库,可通过查阅文档确认是否支持 Tree Shaking(如
lodash-es
支持,lodash
不支持)。
3. 按需引入第三方库
避免整体导入大型库,而是按需引入具体模块。
错误示例:
// 整体导入(包含所有模块)
import _ from 'lodash';
_.map([1, 2, 3]);
正确示例:
// 按需导入(仅包含使用的模块)
import {
map } from 'lodash-es';
map([1, 2, 3]);
工具推荐:
自动按需导入插件(如
unplugin-auto-import
):// vite.config.js import AutoImport from 'unplugin-auto-import/vite'; export default { plugins: [ AutoImport({ imports: ['vue', 'vue-router'], // 自动导入 Vue 和 Vue Router 的 API }), ], };
4. 处理 Vue/React 组件的按需引入
对于 UI 组件库,使用插件自动按需引入。
Vue 示例(Element Plus):
// vite.config.js
import {
defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import {
ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [ElementPlusResolver()], // 自动解析 Element Plus 组件
}),
],
});
React 示例(Ant Design):
// vite.config.js
import {
defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import {
AntDesignResolver } from 'unplugin-vue-components/resolvers';
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
plugins: [
react(),
Components({
resolvers: [AntDesignResolver()], // 自动解析 Ant Design 组件
}),
],
});
5. 避免动态导入与副作用代码
- 动态导入(如
import('./module').then(...)
)会导致 Tree Shaking 失效,尽量使用静态导入。 - 副作用代码(如修改全局变量、DOM 操作)应明确标记在
sideEffects
中。
错误示例:
// 动态导入(无法静态分析)
if (condition) {
import('./module');
}
正确示例:
// 静态导入(顶层声明)
import module from './module';
6. 使用 Vite 插件优化 Tree Shaking
vite-plugin-dts
:生成类型声明文件时保留 Tree Shaking 能力。vite-plugin-optimize-persist
:缓存依赖优化结果,加速构建。
示例配置:
// vite.config.js
import {
defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import dts from 'vite-plugin-dts';
export default defineConfig({
plugins: [
vue(),
dts({
rollupTypes: true, // 生成支持 Tree Shaking 的类型声明
}),
],
});
7. 配置 Rollup 选项(Vite 底层使用 Rollup)
在生产环境中,通过 build.rollupOptions
进一步优化 Tree Shaking。
示例配置:
// vite.config.js
import {
defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
output: {
// 确保第三方库被正确分割
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0];
}
},
},
// 更积极地进行 Tree Shaking
treeshake: {
moduleSideEffects: 'no-external', // 仅保留外部模块的副作用
propertyReadSideEffects: false, // 不考虑属性读取的副作用
unknownGlobalSideEffects: false, // 不考虑未知全局变量的副作用
},
},
},
});
8. 验证 Tree Shaking 效果
使用 vite build --sourcemap
生成 sourcemap,并通过工具分析打包结果:
安装分析工具:
npm install -g source-map-explorer
生成分析报告:
npx source-map-explorer dist/assets/*.js
报告解读:
- 检查是否存在未使用的代码被打包。
- 优化体积较大的模块,确保按需引入。
完整配置示例
// vite.config.js
import {
defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import {
ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import AutoImport from 'unplugin-auto-import/vite';
export default defineConfig({
plugins: [
vue(),
AutoImport({
imports: ['vue', 'vue-router'],
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
build: {
rollupOptions: {
treeshake: {
moduleSideEffects: 'no-external',
propertyReadSideEffects: false,
unknownGlobalSideEffects: false,
},
},
},
});
常见问题与解决方案
问题 | 原因 | 解决方案 |
---|---|---|
第三方库未被 Tree Shaking | 使用 CommonJS 版本或未正确标记 sideEffects | 切换至 ES 模块版本(如 lodash-es ),或在 package.json 中声明 sideEffects |
CSS 被意外移除 | 未标记 CSS 文件的副作用 | 在 package.json 中添加 "*.css" 到 sideEffects |
动态导入导致 Tree Shaking 失效 | 使用 import('./module') 动态加载模块 |
改为静态导入,或使用 vite-plugin-dynamic-import-vars 优化动态导入 |
通过以上配置,Vite 可以充分发挥 Tree Shaking 的优势,大幅减小打包体积,提升应用加载速度。