Und*_*ion 35 javascript side-effects bundler webpack package.json
Webpack 4增加了一项新功能:它现在支持捆绑的模块中的sideEffects标志package.json.
在过去的30天里,我们与每个框架密切合作,以确保他们已准备好在各自的cli等支持webpack 4.即使像lodash-es这样的流行库,RxJS也支持sideEffects标志,所以通过使用他们的最新版本版本,您将看到即时捆绑尺寸减少开箱即用.
"sideEffects":big-module的package.json中的false标志表示包的模块没有副作用(评估时)并且只暴露导出.这允许像webpack这样的工具优化再出口.
虽然第二个链接显示了使用该标志的结果,但它没有清楚地解释什么构成副作用.ES6包含了此处概述的模块副作用的概念,但这与Webpack考虑的副作用有何关系.
在sideEffects标志的上下文中,模块需要避免在sideEffects:false没有问题的情况下使用什么,或者对话,模块需要做什么才能sideEffects:false无问题地使用.
为了完整起见,尽管@ SeanLarkin在下面给出了可靠的答案,但我想对以下内容进行澄清:
显然,副作用意味着fp特有的东西,包括日志记录(控制台或其他地方)和抛出错误.我假设在这种情况下这些是完全可以接受的吗?
模块是否可以包含循环引用并仍然使用sideEffects: false?
有没有办法验证或模块是否能够验证模块是否可以sideEffects: false超越试图追踪由其误用造成的错误?
是否还有其他因素会妨碍模块的使用sideEffects: false?
Sea*_*kin 57
来自webpack团队的肖恩!我会尽力代替我们仍在进行中的文档来回答您的问题!
根据ECMA模块规范(我不打算尝试找到链接所以你必须在这里相信我,因为它被埋没了),
每当一个模块再出口(如果无论使用或不使用的)中的所有出口需要进行评估,并在这些出口中的一个创建与另一个副作用的情况下执行.
例如,我创建了一个带有照片的小方案,以更好地可视化案例:
在这张照片中我们可以看到,3个独立模块与单个导入,导入到一个单独的模块,然后采用这些默认出口,重导出该模块的他们:
你可以在这里看到,没有一个reexport会受到彼此影响,因此(如果给webpack一个信号),我们可以省略导出b,c甚至可以跟踪或使用(大小和构建时间性能优势).
然而,在这种情况下,我们看到出口c被"影响",由当地国家的变化,因为它被重新分配给的总和b及a.因此,(这就是为什么该规范要求这一点),我们需要两者都包括b和a及其任何依赖的成捆.
我们选择"sideEffects:false"作为节省编译时间和构建大小的方法,因为这允许我们立即修剪(显式)开发人员/库作者知道的副作用是免费的(以牺牲属性为代价) package.json,或2-3行配置).
虽然从技术上讲这个例子非常原始,但是当你开始处理Frameworks或Libraries,它们为开发者体验(Three.js,Angular,lodash-es等)重新出口一堆模块时,那么性能提升是显着的. (如果它们是sideEffect free module exports)你以这种方式标记它们.
其他说明:
- 显然,副作用意味着fp特有的东西,包括日志记录(控制台或其他地方)和抛出错误.我假设在这种情况下这些是完全可以接受的吗?
在这是试图解决的情况下,是的.只要对模块出口产生的影响不受其他会导致修剪不可接受的影响.
- 模块是否可以包含循环引用并仍然可以使用
sideEffects: false?
理论上应该这样.
- 有没有办法验证或模块能够使用
sideEffects: false除了试图追踪由其误用造成的错误?
不是我所知道的,但这将是一个很好的工具.
- 是否还有其他因素会妨碍模块的使用
sideEffects: false?
如果属性未在package.json或未定义module.rules,或未mode: production设置(利用优化).
asd*_*ads 10
此sideEffects设置非常模糊,在文档中没有充分描述.文档大多是"有一个sideEffects没有任何副作用的模块的标志".
大家一致认为,"没有副作用"的短语可以被解除为"不与顶层模块外部的事物交谈".
我目前的理解是,这个sideEffects标志仅用于"再出口","再出口"是:
export { a } from './lib/a'
export { b } from './lib/b'
Run Code Online (Sandbox Code Playgroud)
在某处<npm-package>/index.js(或其中的任何其他文件<npm-package>).
如果的WebPack检测应用程序只导入a从<npm-package>,并没有导入b任何地方,然后可以的WebPack简单地丢弃export { b } from './lib/b'从线<npm-package>/index.js导致不包括
'./lib/b.js'在生成的包文件(这使得它的尺寸更小的'./lib/b.js'文件).
现在,如果'./lib/b.js'有一些顶级代码行做一些"副作用",即如果'./lib/b.js'做了类似的事情:
window.jQuery = ...if (!global.Set) global.Set = require('babel-polyfill').Setnew XmlHttpRequest().post('/analytics', data)然后'./lib/b.js'会说它有"副作用",因为它的顶级代码(执行时import './lib/b')会影响'./lib/b.js'文件范围之外的内容.
同时,只要'./lib/b.js'顶级代码没有到达该*.js文件之外,它就没有任何"副作用":
let a = 1
a = a + 1 + computeSomeValue()
export default a
export const b = a + 1
export const c = b + 1
Run Code Online (Sandbox Code Playgroud)
这些都不是"副作用".
还有最后的问题:如果一个npm包有任何*.css文件,用户可以import这些*.css文件都是"副作用",因为:
import 'npm-package/style.css'
Run Code Online (Sandbox Code Playgroud)
没有分配给import它的变量,这实际上意味着"这个导入的模块不会在应用程序的任何地方使用"用于Webpack.因此,'npm-package/style.css'如果npm-package有sideEffects: false标志,Webpack只会丢弃捆绑中的文件作为"树摇动"过程的一部分.所以,而不是写sideEffects: false总是写"sideEffects": ["*.css"].即使你的npm软件包没有导出任何CSS文件,它也可能会在将来发布,这样可以防止上述"CSS文件未包含"错误.
| 归档时间: |
|
| 查看次数: |
8765 次 |
| 最近记录: |