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

时间:2016-04-12 06:12:38

标签: javascript node.js ecmascript-6 webpack commonjs

假设我们有四个模块,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 evaluatedA constructor多少次?

此行为是否在 ES6标准中描述?如果我想要仅对一个模块进行评估,无论直接或间接导入多少次,我该怎么办?有没有人对此有任何想法?

1 个答案:

答案 0 :(得分:23)

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

A evaluated
A constructor

这意味着A模块只评估过一次,即使它被其他模块多次导入。

ES6 modules的评估规则与commonjs格式的评估规则相同:

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

ECMAScript 6规范的HostResolveImportedModule部分描述了导入模块的同一实例的行为。
它提到:

  

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

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