ES Modules のインポート順は保証されるのかされないのか
結論
順番は保証される。
経緯
こんな Stack Overflow を見た。
https://stackoverflow.com/questions/35551366/what-is-the-defined-execution-order-of-es6-imports
質問
code: one.js
console.log("one");
code: two.js
console.log("two");
code: js
import "one";
import "two";
console.log("three");
というコードがあったときに
code: console
one
two
three
が保証されるのか。
ベストアンサー
Exploring JS §16.6.1 によると
1. Load modules synchronously, while the body is executed. That is what Node.js does.
2. Load all modules asynchronously, before the body is executed. That is how AMD modules are handled. It is the best option for browsers, because modules are loaded over the internet and execution doesn’t have to pause while they are. As an added benefit, this approach allows one to load multiple modules in parallel.
という記述があり、Node.js のようにモジュールが同期的に読み込める場合は保証されるが、ブラウザのようにモジュールを非同期に読み込む場合は実行順は保証されない。つまり
code: console
two
one
three
もあり得る。
誤解の元
そもそも JavaScript のモジュールは読み込み、パース、実行の3つのステップに分かれる。確かに読み込み時点では非同期なため順番は保証されないが、実行順については保証される。
ES2015 §15.2.1.16.5 によるとモジュールがもつ [[RequestedModules]] の順に実行されることがわかり、そしてそれは ES2015 §15.2.1.16 によりソースコードにおける発生順だと明記してある。
思ったこと
ブラウザで実行されるアプリケーションを開発する際にはだいたいバンドラーを使うため、そういうものなのかと思ってしまったが、ちゃんと仕様を確認すべきだった。
TC39 メンバーの Jordan Harband さんに突っ込まれてしまったので反省する。