Подтвердить что ты не робот

В синтаксисе `import` ES6, как точно вычисляется модуль?

Скажем, у нас есть четыре модуля: A, B, C и D

В модуле 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? Что делать, если я хочу, чтобы модуль оценивался ТОЛЬКО один раз независимо от того, сколько раз импортируется прямо или косвенно? У кого-нибудь есть идеи об этом?

4b9b3361

Ответ 1

Когда модуль D будет выполнен, консоль напечатает это сообщение:

A evaluated
A constructor

Это означает, что модуль A оценивался только один раз, даже если он несколько раз импортировался другими модулями.

Правила оценки для ES6 modules такие же, как для формата commonjs:

  • Модуль представляет собой кусок кода, который выполняется после его загрузки. Это означает, что если модуль не включен в основной пакет, он не будет оцениваться
  • Модули - это синглтоны. Если модуль импортируется несколько раз, существует только один instance, и он оценивается только один раз при загрузке

Поведение импорта одного и того же экземпляра модуля описано HostResolveImportedModule в спецификации ECMAScript 6.

В нем упоминается:

Эта операция (операция импорта) должна быть идемпотентной, если она завершается нормально. Каждый раз он вызывается с помощью конкретной пары реферирования, пары спецификаторов (import <a> from <source> ) как аргументы должны возвращать тот же экземпляр записи модуля.

Поведение однократной оценки модуля описано в ModuleEvaluation, пункты 4 и 5, используя Evaluated логический флаг.
Каждый модуль имеет флаг Evaluated, который обязательно оценивает код модуля только один раз.