5

If I have the following:

<script type="module" src="one.js"></script>
<script type="module" src="two.js"></script>
<script type="module" src="three.js"></script>
  1. Am I right in saying that you cannot be 100% sure that three.js will be executed AFTER one.js and two.js?

However, if I have:

<script type="module">
  import 'one.js'
  import 'two.js'
  import 'three.js'
</script>
  1. 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)

Commentary on possible duplicates

I know it looks like a duplicate question, but please keep in mind that the aim of this question is to confirm the very different behaviour of importing via HTML and via JavaScript

halfer
  • 19,824
  • 17
  • 99
  • 186
Merc
  • 16,277
  • 18
  • 79
  • 122
  • If you want to ensure that `three` is executed after `one` and `two`, import those two into `three` itself (and avoid circular dependencies). Do not rely on the order of imports in your main module. – Bergi Sep 05 '21 at 14:32
  • IIRC, top-level `await` broke the assumption that modules are executed in import order. – Bergi Sep 05 '21 at 14:33
  • 0x6368656174's answer has a point -- and a link to documentation...! – Merc Sep 05 '21 at 14:57

3 Answers3

2

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

Yes, because for example three.js may have already been imported in one.js, and modules are evaluated only once.

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)

No, for the same reason as above.

In both ways of importing a module, if none of the modules had been imported previously then they would be evaluated in the same order they appear in the markup or code.

In the ECMAScript specification, see the 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.

When importing a module using a script tag with the src attribute, if the order of evaluation is not important the async attribute can be used to execute it as soon as it is downloaded.

MikeM
  • 13,156
  • 2
  • 34
  • 47
1

In general, if all modules don't have mutual imports in the both cases are executed modules in the same orders.

In the first case type module works like defer script. Code is executed in the correct order after DOM is loaded. It said in the documentation of defer https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer (yellow the box and the next paragraph).

In the second case imports, as you expect, are runs in order that they define in file.

0x6368656174
  • 992
  • 5
  • 13
  • Do you have a source for this? – A_A Sep 05 '21 at 13:39
  • 1
    "In the first case scripts will be executed in the same order." <--- I very much doubt it. If it does it's not GUARANTEED to be executed in the same order. I might be wrong -- do you have a source for this? – Merc Sep 05 '21 at 13:42
  • @Merc Yes, it is said in documentation https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer Read yellow box and the next paragraph. – 0x6368656174 Sep 05 '21 at 13:47
1

No, it's not guaranteed to run in same order. It depends on all other files and imports.

Es6 modules are evaluated only once. It means an import statement does not mean an evaluation. When the first host module (module that imports Òne.js or Two.js) gets executed, then the imported modules get evaluated. And the same instance will be provided for further imports.

Say A.js imports Two.js and gets executed first and B.js runs afterwards and B.js imports both One.js and Two.js (assuming only these two file import these modules). then in time B.js gets executed Two.js already evaluated but One.js has to be evaluated now.

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

Mike Ezzati
  • 2,968
  • 1
  • 23
  • 34
  • Are you answering (1) or (2)? – Merc Sep 05 '21 at 14:54
  • I think you are confusing the fact that modules are only evaluated once with the question on whether the order is respected. Documentation seems to confirm that the order is preserved (see 0x6368656174's answer). – Merc Sep 05 '21 at 15:02
  • I answered the second part. Its much more complicated than you think. As I said in my answer, order is preserved only if there is one module in your entire application that is importing one.js and two.js. most times there are more than one module that imports modules. In that case order is not guaranteed. – Mike Ezzati Sep 05 '21 at 15:26