Webpack 4从带有副作用的程序包中期望什么:false

Webpack 4 has added a new feature: it now supports a sideEffects flag in the package.json of the modules it is bundling.

From Webpack 4: released today

Over the past 30 days we have worked closely with each of the frameworks to ensure that they are ready to support webpack 4 in their respective cli’s etc. Even popular library’s like lodash-es, RxJS are supporting the sideEffects flag, so by using their latest version you will see instant bundle size decreases out of the box.

From Webpack docs

The "sideEffects": false flag in big-module's package.json indicates that the package's modules have no side effects (on evaluation) and only expose exports. This allows tools like webpack to optimize re-exports.

Whilst the second link shows the results of using the flag, it doesn't clearly explain what constitutes a side-effect. ES6 includes the concept of side-effects for modules as outlined here, but how does this relate to what Webpack considers side-effects.

In the context of the sideEffects flag, what does a module need to avoid to use sideEffects:false without issues, or conversly, what does a module need to do in order to use sideEffects:false without issues.

For completeness, despite @SeanLarkin's solid answer below, I would love to get clarification on the following:

  1. Obviously side-effects means something particular in fp and would include logging (console or elsewhere) and the throwing of errors. I'm assuming in this context these are perfectly acceptable?

  2. 模块可以包含循环引用并且仍在使用sideEffects: false吗?

  3. 是否有任何方法可以验证或模块能够验证模块是否可以sideEffects: false尝试追查由于滥用而导致的错误?

  4. 还有其他因素会阻止模块使用sideEffects: false吗?

十三LEY2020/03/24 18:21:48

webpack团队的肖恩!我会尽力代替仍在处理中的文档,在这里回答您的问题!

根据ECMA模块规范(我不会尝试查找链接,因此您必须在这里信任我,因为它被埋藏了),

每当模块重新导出所有导出(无论使用或未使用)时,如果其中一个导出与另一个导出产生了副作用,则需要对其进行评估和执行。

例如,我用照片创建了一个小场景,以更好地形象化此案例:

在这张照片中,我们看到三个模块导入到一个文件中。导入的模块然后从该模块重新导出

重新导出的模块无副作用的示例

您可以在此处看到任何再导出都不会相互影响,因此(如果向webpack发出了信号),我们可以省略导出bc甚至可以不对其进行跟踪或使用(大小和构建时间性能优势)。

在此处输入图片说明

然而,在这种情况下,我们看到出口c被“影响”,由当地国家的变化,因为它被重新分配给的总和ba因此,(这就是为什么这种情况的规范要求),我们需要两者都包括ba及其任何依赖的成捆。

我们选择“ sideEffects:false”作为节省编译时间和构建大小的一种方法,因为这使我们可以立即(显式)修剪开发人员/库作者知道没有副作用的导出(以牺牲一个属性为代价)。 package.json或另外2-3行的配置)。

尽管从技术上来说,此示例非常原始,但是当您开始处理框架或库时,这些框架或库重新导出一堆模块以达到更高的开发人员体验级别(Three.js,Angular,lodash-es等),则在以下情况下性能提升显着(如果它们是sideEffect自由模块导出),则以这种方式标记它们。

其他说明:

  1. 显然,副作用是指fp中的某些特殊现象,包括日志记录(控制台或其他地方)和引发错误。我假设在这种情况下,这些完全可以接受吗?

在尝试解决的情况下,可以。只要针对模块导出创建的效果不会受到其他因素的影响,否则会导致修剪不可接受。

  1. 一个模块可以包含循环引用并且仍然可以使用吗 sideEffects: false?

从理论上讲应该如此。

  1. sideEffects: false除了试图追踪由于误用导致的错误之外,还有没有其他方法可以验证模块是否可以使用

我不知道,但是这将是一个很好的工具。

  1. 还有其他因素会阻止模块使用sideEffects: false吗?

如果该属性不在中,或者未在中package.json定义module.rules,或者mode: production未设置(利用优化)。