ES6 导入的执行顺序,在 HTML 和代码中

Execution order of ES6 imports, in HTML and in code

如果我有以下情况:

<script type="module" src="one.js"></script>
<script type="module" src="two.js"></script>
<script type="module" src="three.js"></script>
  1. 我说的对吗,您不能 100% 确定 three.js 会在 one.jstwo.js 之后执行?

但是,如果我有:

<script type="module">
  import 'one.js'
  import 'two.js'
  import 'three.js'
</script>
  1. 我是否可以确信 three.js 将在 one.jstwo.js 之后执行? (这很重要)

对可能重复项的评论

我知道这看起来像是一个重复的问题,但请记住,这个问题的目的是确认通过 HTML 和通过 JavaScript[=19 导入的非常不同的行为=]

一般来说,如果所有模块没有相互导入,在这两种情况下都是以相同的顺序执行模块。

在第一种情况下,类型 module 的工作方式类似于 defer 脚本。加载 DOM 后,代码以正确的顺序执行。它在 defer https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer 的文档中说(黄色框和下一段)。

在第二种情况下,如您所料,导入是按照它们在文件中定义的顺序运行的。

Am I right in saying that you cannot be 100% sure that three.js will be executed AFTER one.js and two.js?

是的,因为例如 three.js 可能已经在 one.js 中导入,模块只评估一次。

Am I right in saying that I can be confident that three.js will be executed AFTER one.js and two.js? (this is important)

没有,同上。

在两种导入模块的方式中,如果之前导入了 none 个模块,那么它们将按照它们在标记或代码中出现的顺序进行评估。

在 ECMAScript 规范中,参见 ModuleEvaluation method which iterates through a Source Text Module Record's RequestedModules:

A List of all the ModuleSpecifier strings used by the module represented by this record to request the importation of a module. The List is source code occurrence ordered.

使用带有 src 属性的脚本标签导入模块时,如果求值顺序不重要,可以使用 async 属性在下载后立即执行它。

不,不能保证 运行 的顺序相同。这取决于所有其他文件和导入。

Es6 模块只评估一次。这意味着导入语句并不意味着评估。当第一个主机模块(导入 Òne.jsTwo.js 的模块)被执行时,导入的模块就会被评估。并且将提供相同的实例以供进一步导入。

A.js 导入 Two.js 并首先执行 B.js 运行s 然后 B.js 导入 One.jsTwo.js(假设只有这两个文件导入这些模块)。然后及时 B.js 被执行 Two.js 已经评估但 One.js 现在必须评估。

https://262.ecma-international.org/6.0/#sec-hostresolveimportedmodule