Tree Shaking 为什么没把我的 Vue 组件里没用的函数删掉?

シ晓英 阅读 3

我用 Vite + Vue 3 开发,发现打包后一些没引用的工具函数还在 bundle 里。明明开启了 Tree Shaking,是不是因为 sideEffects 配置不对?

比如下面这个组件,只用了 formatDate,但 unusedHelper 也被打包进去了:

<script setup>
import { formatDate, unusedHelper } from '@/utils/dateUtils'

const time = formatDate(new Date())
// unusedHelper 完全没被调用
</script>

<template>
  <div>{{ time }}</div>
</template>

我已经在 package.json 里设了 "sideEffects": false,但还是没效果,是不是 Vue 单文件组件的问题?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
皇甫沐语
你这个问题我之前也踩过坑,其实不是 Tree Shaking 坏了,是你理解有偏差。

先说结论:你在组件里显式 import 了 unusedHelper,虽然没调用,但这个 import 语句本身会被 Vue 编译器处理。Rollup 在分析依赖时,看到这个 import 存在,保守起见会保留它,尤其是当你的 dateUtils.js 文件可能有副作用时。

解决方案有两个层面。

第一层,最直接的办法——别 import 你不需要的东西。这听起来像废话,但代码洁癖真的很重要。可以优化成只 import 你实际用到的:

import { formatDate } from '@/utils/dateUtils'

const time = formatDate(new Date())


第二层,如果你确定 dateUtils.js 是纯函数无副作用,确保 sideEffects 配置生效。你只说在 package.json 配了,但这个配置是针对整个包的。如果你的工具文件在 src 目录下,需要在 vite.config.js 里明确告诉 Rollup:

export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: undefined
}
}
}
})


另外,检查一下你打包时是不是用的生产模式,开发模式下的 Tree Shaking 效果很有限。跑一下 npm run build,用 npx vite-bundle-visualizer 看看实际的打包结果,别光看源码猜。

还有个容易忽略的点,如果你的 dateUtils.js 里写了类似立即执行的表达式,比如:

// 这玩意儿会被认为有副作用
console.log('dateUtils loaded')

export function formatDate() { ... }
export function unusedHelper() { ... }


这种情况下 sideEffects: false 也救不了你,整个文件都会被保留。把副作用代码清掉,Tree Shaking 才能正常工作。

养成个好习惯,用 ESLint 的 no-unused-vars 规则,这种无用的 import 在编码阶段就该被揪出来干掉。
点赞
2026-03-03 00:05