在 package.json 中通过 "sideEffects" 字段声明无副作用文件:设为 false 表示全包无副作用;设为数组如 ["*.css", "src/init.js"] 显式列出有副作用文件;true 或不写则禁止摇树。CSS 等资源需显式声明,否则样式丢失;类型文件 .d.ts 无需处理;动态 import 不受控制。

在 package.json 中正确声明无副作用(side-effect-free)文件,核心是通过 "sideEffects" 字段告诉打包工具(如 Webpack、Rollup、Vite)哪些模块可以安全地被摇树(tree-shake),哪些不能。这直接影响最终打包体积和运行时行为。
什么是“无副作用”?
一个模块若只导出值(如函数、常量、类型),且执行时不会修改全局状态、不触发网络请求、不操作 DOM、不产生日志或副作用 I/O,就可视为“无副作用”。例如:
export const PI = 3.14159;export function add(a, b) { return a + b; }-
export default class Utils { ... }(仅定义,未 new 或调用)
但若模块顶部写了 console.log('init')、localStorage.setItem(...) 或 require('./polyfill'),它就有副作用,不能被随意移除。
如何在 package.json 中配置 sideEffects
"sideEffects" 是一个布尔值或字符串数组,位于 package.json 的顶层:
立即学习“Java免费学习笔记(深入)”;
-
"sideEffects": false:表示整个包所有模块都无副作用,可被完全摇树。适用于纯函数式工具库(如lodash-es的部分子集、date-fns)。 -
"sideEffects": ["*.css", "*.scss", "src/init.js"]:显式列出有副作用的文件路径(支持 glob 模式)。其余文件默认视为无副作用。 -
"sideEffects": true(默认行为):等价于不写该字段,即所有文件都可能有副作用,禁止摇树导入的模块。
⚠️ 注意:"sideEffects": false 不代表“不执行”,而是“执行也不影响程序逻辑”,所以必须确保你声明的每个文件真的满足条件。
常见误用与建议
以下情况容易出错,需特别注意:
-
CSS/资源文件必须显式列出:即使你只用
import './index.css',Webpack 也会因副作用机制保留它 —— 所以要把"*.css"加入sideEffects数组,否则样式会丢失。 -
入口文件(如 index.js)若有副作用,不能依赖
false:比如index.js自动注册全局插件或 polyfill,此时应设为["index.js"]或更精确路径。 -
TypeScript 类型文件(.d.ts)不影响运行时,无需声明:它们不参与打包,
sideEffects对其无意义。 -
动态
import()不受此字段控制:该字段只影响静态import的摇树判断。
验证是否生效
配置后,可通过以下方式确认效果:
- 用 Webpack 构建后查看生成的 bundle,搜索已导入但未使用的导出是否被剔除;
- 在项目中只
import { debounce } from 'your-lib',检查打包结果里throttle是否不存在; - 使用
rollup --treeshake=verbose查看摇树日志; - Vite 用户可开启
build.rollupOptions.treeshake: 'recommended'并观察产物大小变化。
不复杂但容易忽略 —— 一个准确的 sideEffects 声明,能让使用者获得更小、更干净的打包结果。


















