Tree Shaking 为什么没把我的 Vue 组件里没用的函数删掉?
我用 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 单文件组件的问题?
先说结论:你在组件里显式 import 了
unusedHelper,虽然没调用,但这个 import 语句本身会被 Vue 编译器处理。Rollup 在分析依赖时,看到这个 import 存在,保守起见会保留它,尤其是当你的dateUtils.js文件可能有副作用时。解决方案有两个层面。
第一层,最直接的办法——别 import 你不需要的东西。这听起来像废话,但代码洁癖真的很重要。可以优化成只 import 你实际用到的:
第二层,如果你确定
dateUtils.js是纯函数无副作用,确保 sideEffects 配置生效。你只说在 package.json 配了,但这个配置是针对整个包的。如果你的工具文件在 src 目录下,需要在 vite.config.js 里明确告诉 Rollup:另外,检查一下你打包时是不是用的生产模式,开发模式下的 Tree Shaking 效果很有限。跑一下
npm run build,用npx vite-bundle-visualizer看看实际的打包结果,别光看源码猜。还有个容易忽略的点,如果你的
dateUtils.js里写了类似立即执行的表达式,比如:这种情况下 sideEffects: false 也救不了你,整个文件都会被保留。把副作用代码清掉,Tree Shaking 才能正常工作。
养成个好习惯,用 ESLint 的
no-unused-vars规则,这种无用的 import 在编码阶段就该被揪出来干掉。