在 vite 中,tree shaking 默认生效且无需额外配置,因为它底层依赖 es modules (esm) 的静态结构特性。只要确保代码中使用的是 esm 语法(即 import 和 export),vite 就会自动剔除未使用的导出。对于第三方库,如果其发布的包中包含 package.json 并正确标记了 sideeffects 字段,vite 也能安全地移除副作用代码。

如何确保本地代码被正确摇树优化
要确保本地编写的模块能被 Vite 正确优化,核心在于遵循纯函数和无副作用的开发规范。Vite 通过静态分析导入关系来识别死代码,因此必须避免在模块顶层执行不可逆的操作。例如,如果在文件顶部直接修改全局变量或发起网络请求,构建工具会认为该模块具有“副作用”,从而强制引入整个文件,即使你只导入了其中某个未被调用的函数。开发者应检查自己的工具函数库,确保它们仅包含数据转换逻辑,不触碰外部状态。

// utils/math.js
// ✅ 正确:纯函数,无副作用,可被 Tree Shaking
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// main.js
import { add } from './utils/math.js';
console.log(add(1, 2)); // multiply 将被剔除
在实际项目中,常见的陷阱是混用 CommonJS 和 ESM。虽然 Vite 能处理 CJS 转 ESM 的兼容层,但 CJS 模块本身无法被静态分析进行细粒度的 Tree Shaking。因此,在编写新库或重构旧代码时,应始终使用 export const 或 export default 等标准 ESM 语法。此外,若使用了 Babel 或 TypeScript 编译,需确保输出格式为 es,否则生成的代码可能破坏静态分析的完整性。
立即学习“Java免费学习笔记(深入)”;
如何处理带有副作用的第三方库
当引入如 lodash 或 axios 等广泛使用的库时,Tree Shaking 的效果取决于这些库自身的发布配置。许多传统库为了兼容性,会在 package.json 中将 sideEffects 设置为 true 或省略该字段,这会导致 Vite 认为加载该库会改变应用状态,进而打包整个库而非按需引入。解决这一问题的方法是确认库是否提供了 ESM 入口,或者手动配置 Vite 的优化选项来声明哪些文件是安全的。
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
// 显式声明某些文件有副作用,防止被误删
// 或者利用 external 排除大型库
external: ['some-large-lib'],
},
},
});
对于现代前端库,通常建议直接使用其 ESM 版本。例如,与其导入整个 lodash,不如使用 lodash-es,后者专为 Tree Shaking 设计。如果必须使用带有副作用的库(如注册全局样式的 CSS 文件或 polyfill),则不应期望 Tree Shaking 能减小其体积,而应将其视为必要的运行时依赖。开发者可以通过检查构建产物中的 bundle 大小来验证优化效果,未使用的代码块不应出现在最终的 JS 文件中。
生产构建与开发模式下的行为差异
理解 Vite 在不同模式下的行为对于调试 Tree Shaking 至关重要。在开发模式下 (vite serve),Vite 使用原生 ES Modules,服务器按需提供模块,此时并不进行真正的打包和压缩,因此 Tree Shaking 主要体现为浏览器只请求了实际导入的文件。而在生产构建模式下 (vite build),Vite 调用 Rollup 进行完整的打包、压缩和 Tree Shaking,此时未使用的代码会被彻底从输出文件中移除。
// package.json scripts
{
"scripts": {
"dev": "vite", // 开发模式:按需加载,无完整打包
"build": "vite build" // 生产模式:完整打包,执行 Tree Shaking
}
}
这种差异意味着,如果你在开发环境中发现某个未使用的组件似乎“被加载”了,这通常是正常的,因为浏览器正在解析模块图。只有运行 vite build 后,你才能看到最终的体积缩减效果。建议在开发阶段专注于功能正确性,而在部署前务必运行生产构建命令,并使用 --report 参数生成构建分析报告,以直观查看哪些模块被保留,哪些被剔除。同时,注意检查是否有意外的全局变量污染导致 Rollup 无法安全地删除某些代码块。


















