引子
前段时间开发UI组件库,目的之一为了替代掉NutUI
,减小微信小程序主包体积。初版完成后,尝试接入小程序,猛然发现包体积不减反增,主包没有用到的组件也全部打入了主包中。研究后发现在package.json
中加入一行sideEffects
的配置,就能解决问题,效果拔群。那什么是sideEffects
?
sideEffects
sideEffects
是一个package.json
中的一个字段,用于告诉打包工具哪些模块文件是有副作用的。在JavaScript
中,副作用指的是执行某个操作时,除了返回值之外,还会对程序状态产生影响的行为。例如,修改全局变量、进行网络请求、写入文件系统等。
在package.json
中,sideEffects
可以是一个布尔值或一个数组。具体配置如下:
- 布尔值:
-
false
:表示整个项目中的所有模块都没有副作用,可以安全地进行 tree-shaking。true
:表示项目中有部分模块有副作用,需要手动指定哪些模块有副作用。
- 数组:
-
- 列出有副作用的模块文件路径。例如:
{
"sideEffects": ["./src/some-side-effectful-file.js"]
}
tree-shaking
tree-shaking
是一种优化技术,用于消除未使用的代码,从而减小最终打包文件的体积。它主要依赖于ES6
模块的静态结构特性。当打包工具进行构建时,会分析模块的导入和导出关系,识别出哪些代码是未被引用的,并将其从最终的打包文件中移除。
感兴趣可以进一步阅读webpack
官方文档中有关tree-shaking
的部分【webpack.js.org/guides/tree…】。
sideEffects与tree-shaking的关系
在100%ES6
模块世界中,识别副作用非常简单。但是,我们还没有做到这一点,所以我们有必要向打包工具提供有关代码“纯度”的提示。因此,sideEffects
标识符对于tree-shaking
至关重要。如果一个模块被标记为有副作用,打包工具就不会对其进行tree-shaking
,即使该模块中的某些部分未被使用。这是因为这些副作用可能会导致程序行为的变化,删除它们可能会引发错误。
例如,假设你有一个模块utils.js
,其中包含一些辅助函数和一些副作用代码:
console.log('This is a side effect');
export function add(a, b) {
return a + b;
}
如果你在package.json
中将utils.js
标记为有副作用:
{
"sideEffects": ["./src/utils.js"]
}
那么即使你在项目中只使用了add
函数,console.log
语句也会被保留,因为它是有副作用的。
实践案例
回到我的组件库开发过程中,我最初没有考虑sideEffects
的问题,导致所有组件都被打包进了主包中。通过在package.json
中添加sideEffects
配置,我指定了哪些文件是有副作用的,从而让Webpack
能够更准确地进行tree-shaking
,实现按需编译。
总结
sideEffects
和tree-shaking
是现代前端开发中非常重要的优化手段。通过合理配置sideEffects
,我们可以帮助打包工具更准确地识别和移除未使用的代码,从而显著减小最终打包文件的体积,提升应用的性能。希望本文能帮助你更好地理解和应用这些技术。