一尘不染

在ES6的`import`语法中,如何准确评估模块?

node.js

比方说,我们有四个模块ABCD

在模块中A

console.log("A evaluated")
function AClass {
  console.log("A constructor")
}
var aObj = new AClass()
export default aObj;

在模块中B

import aObj from A
export default "B"

在模块中C

import aObj from A
export default "C"

在模块中D

import b from B
import c from C
import aObj from A

因此,在D评估模块时,将在控制台中打印A evaluated和多少次A constructor

ES6标准中 描述了此行为吗?如果我希望一次仅评估一个模块而不论直接或间接导入多少次,该怎么办?有人对此有任何想法吗?


阅读 244

收藏
2020-07-07

共1个答案

一尘不染

D执行模块,控制台将打印此消息:

A evaluated
A constructor

这意味着该A模块仅被评估一次,即使它被其他模块多次导入也是如此。

的评估规则ES6 modulescommonjs格式相同:

  • 模块是加载后执行的一段代码。这意味着,如果主捆绑包中未包含某个模块,则不会对其进行评估
  • 模块是单例。如果模块多次导入,则仅instance存在一个模块,并且在加载时仅对其进行一次评估

ECMAScript 6规范的HostResolveImportedModule部分介绍了
导入模块相同实例 的行为。 它提到:

如果此操作 (导入操作) 正常完成,则必须是幂等的。每次使用特定的referenceencingModule,说明符对 (从
导入_作为参数
)_ 调用它时,它必须返回相同的Module Record实例。

使用布尔标志在ModuleEvaluation的第4点和第5点中描述了模块的 单次评估
的行为。 每个模块都有标志,可确保仅对模块代码进行一次评估。Evaluated
Evaluated

2020-07-07