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

5
如果我拥有以下内容:
<script type="module" src="one.js"></script>
<script type="module" src="two.js"></script>
<script type="module" src="three.js"></script>
  1. 我说你不能百分之百确定 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导入的非常不同的行为。


如果你想确保 threeonetwo 之后执行,那么将这两个导入到 three 中(避免循环依赖)。不要依赖于主模块中的导入顺序。 - Bergi
如果我没记错的话,顶级 await 打破了模块按导入顺序执行的假设。 - Bergi
0x6368656174的回答有道理——还附带了文档链接...! - Merc
3个回答

2

我说的没错,你无法百分之百确定three.js会在one.js和two.js之后执行,对吗?

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

我说的没错,我可以相信three.js会在one.js和two.js之后执行吗?(这很重要)

不行,原因与上述相同。

在导入模块的两种方式中,如果没有任何模块被先前导入,则它们将按照它们在标记或代码中出现的顺序进行评估。

在ECMAScript规范中,请参见ModuleEvaluation方法,该方法迭代一个Source Text Module Record的RequestedModules

列出此记录表示的模块用于请求模块进口的所有ModuleSpecifier字符串列表。该列表按源代码出现顺序排序。

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


1
一般来说,如果所有模块都没有相互引用,则两种情况下执行的模块顺序相同。
在第一种情况下,类型为module的代码类似于defer脚本。在DOM加载完成后按正确顺序执行代码。这在deferhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer(黄框和下一段)的文档中有所说明。
在第二种情况下,按照文件中定义的顺序运行导入。

你有这个的来源吗? - A_A
1
“在第一种情况下,脚本将按照相同的顺序执行。”<---我非常怀疑这一点。如果是这样,它并不能保证以相同的顺序执行。我可能是错的--你有这方面的来源吗? - Merc
@Merc 是的,在文档中有提到 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer 请阅读黄色框和下一段。 - 0x6368656174

1
不,不能保证以相同的顺序运行。它取决于所有其他文件和导入的内容。Es6模块仅会被评估一次,这意味着导入语句并不意味着评估。当第一个宿主模块(导入 "One.js" 或 "Two.js" 的模块)被执行时,然后导入的模块将被评估。并且同一个实例将为进一步的导入提供。例如,假设 "A.js" 首先导入 "Two.js" 并被执行,之后 "B.js" 运行并导入 "One.js" 和 "Two.js"(假设只有这两个文件导入这些模块),那么在执行 "B.js" 时,"Two.js" 已经被评估,但现在必须评估 "One.js"。

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


你回答的是(1)还是(2)? - Merc
我认为你混淆了模块只被评估一次的事实和是否尊重顺序的问题。文档似乎确认顺序是保留的(请参见0x6368656174的答案)。 - Merc
我回答了第二部分。它比你想象的要复杂得多。正如我在我的答案中所说,只有在您的整个应用程序中有一个模块导入one.js和two.js时,才会保留顺序。大多数情况下,有多个模块导入模块。在这种情况下,顺序不能保证。 - Mike Ezzati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接