在 package.json
中配置 "sideEffects": false
是一个非常重要的 工程化优化配置,它直接影响 Webpack、Vite、Rollup 等现代前端构建工具的 Tree Shaking(摇树优化)行为。
我们来深入解析这里的“副作用”到底是什么意思。
一、“副作用”(sideEffects)在这里是什么意思?
在 JavaScript 模块系统中,“副作用”指的是模块在被导入时,除了导出值之外,还会执行一些其他操作,这些操作可能会影响程序的其他部分。
有副作用的例子:
// utils.js
console.log("This module has side effects!"); // ← 这是一段副作用代码
export const add = (a, b) => a + b;
// polyfill.js
// 这个模块没有导出任何东西,但它修改了全局对象
Array.prototype.myCustomMethod = function () {
/* ... */
}; // ← 副作用:修改全局原型
// theme.css
body { background: red; } // ← 副作用:执行时会应用样式
这些代码虽然可能没有 export
,但它们在被引入时会执行某些逻辑,比如:
- 修改全局对象
- 注册事件监听
- 执行
console.log
- 注入 CSS 样式
- 注册服务 worker 等
这些都被称为 “副作用”。
二、"sideEffects": false 的作用
当你在 package.json
中写:
{
"sideEffects": false
}
你是在告诉构建工具(如 Webpack):
“这个包里的所有模块都是 纯的(pure),没有任何副作用。如果某个模块没有被使用到,即使它被导入了,也可以安全地移除。”
效果:启用更激进的 Tree Shaking
例如,你只用了库中的一个函数:
import { debounce } from "lodash-es";
由于 lodash-es
的 package.json
声明了 "sideEffects": false
,构建工具就知道:其他未被引用的模块(如 throttle
, cloneDeep
等)可以安全删除,最终打包体积更小。
三、"sideEffects": false vs "sideEffects": []
配置 | 含义 |
---|---|
"sideEffects": false |
整个包都没有副作用,可以对所有未使用的模块进行 Tree Shaking。 |
"sideEffects": ["./dist/style.css", "./polyfill.js"] |
大部分模块无副作用,但列出的这些文件有副作用,不能被摇掉。 |
示例:
{
"sideEffects": [
"*.css", // 所有 CSS 文件都有副作用(会注入样式)
"./polyfills.js" // 这个文件会修改全局环境
]
}
这样,构建工具就会保留这些文件,即使它们没有被显式“使用”。
四、实际工程意义
优点:
- 减小打包体积:未使用的代码会被完全移除。
- 提升加载性能:更小的 JS 文件意味着更快的下载和解析。
- 现代框架标配:React、Vue、Lodash、Moment.js 等主流库都合理配置了
sideEffects
。
注意事项:
- 如果你写了一个库,并且包含 CSS、polyfill 或全局初始化逻辑,不能简单设置
sideEffects: false
,否则这些代码可能被误删。 - 应用项目(App)通常不需要关心这个,但库(Library)开发者必须正确配置。
五、常见误区
误解 | 正解 |
---|---|
“sideEffects 是指函数有副作用” | 不是。这里指的是 模块级别 的副作用,不是函数式编程中的“纯函数”。 |
“设置 false 就能自动优化” | 不一定。你还得用 ES Module 语法(import/export ),并且代码要支持静态分析。 |
“所有项目都要加” | 只有当你发布一个 npm 包时才需要配置。应用项目可不写。 |
总结
关键点 | 说明 |
---|---|
sideEffects |
指模块在导入时是否执行了除导出之外的操作(如改全局、打日志、加样式)。 |
"sideEffects": false |
告诉构建工具:“这个包是纯的,可以放心删除未使用的模块”。 |
核心价值 | 支持更高效的 Tree Shaking,减小最终打包体积。 |
适用场景 | 主要用于 npm 库的发布,让使用者获得更小的 bundle。 |
💡 简单记忆:
“没有副作用” = “可以安全删除没用的代码”
“有副作用” = “哪怕没引用,也不能删”(比如 CSS 文件)