ESM
>The good news is that modern browsers have started to support module functionality natively, and this is what this article is all about.
>browsers can optimize loading of modules, making it more efficient than having to use a library and do all of that extra client-side processing and extra round trips.
ESMはJavaScriptのモジュールシステム
10年近く標準化にかかったけどそろそろ終わりそう
ESMをサポートするのは
主要なブラウザ(Firefox 60〜)
仕様策定
モジュールの読み込み
ESMのsyntax, JSのルール
例: this
の扱い
ESMがどんな問題を解決して、他のモジュールシステムとどう違うのかを解説
モジュールが解決する問題
前提:JavaScriptにおいて、変数は関数のスコープ内に閉じ込められる
他の関数から参照されないので、よい
問題:変数を関数のスコープ外でどう共有すればいいか?
古来から行われてきた方法:グローバルスコープで共有する
jQueryがグローバルになかったらjQueryを期待するプラグインは実行時エラーになる
この方法の良くない点
この方法は、scrpitタグの順序が正しくなければいけないので、管理が複雑になる
どんな関数もグローバルのオブジェクトを利用でき、暗黙的な依存が発生する
悪意のあるコードは意図的にグローバルの変数を破壊できる
モジュールを使うと、この問題を解決できる
modulesのスコープに関数と変数を閉じ込める
関数スコープと違って変数を他のモジュールでも利用できる
import/exportで明示的に行うので、暗黙的な依存性はない
いま利用されているモジュールシステム
Node.jsが作った
CJS(歴史的にこちらのほうが古い)
ESモジュールのしくみ
ESMをロードするとmodule instanceができる
モジュールを使って開発するのは、依存性グラフをつくっているのと同じ
import文はブラウザやNodeがどのファイルを読めばいいのか指示する。このためブラウザはエントリポイントから入ってimport文をたどってすべてのファイルを見つけることができる
module recordはmodule instanceに変換される
module instanceは2つの要素の組み合わせ
コード(instructionのリスト)
状態(変数の値)
すべてのモジュールのmodule instanceを得たい
各モジュールのmodule instanceが必要になる。エントリポイントからmodule instanceのすべてのグラフをロードすることになる。これは3ステップからなる(詳細は後述)
1. construction
2. instantiation
3. evaluation
CJSとの違い
CJSはmoduleとその依存関係がインスタンス化されて一気に評価される
ESMはフェーズが非同期的に実行される
ESMのspec、実行環境のspec
ESMのspecはファイルをパースしてmodule recordsにし、moduleをインスタンス化して評価する方法について定義してある。
一方で、どのファイルを最初に取得するかは未定義。どのようにロードするかは環境による。
ローダがファイルを取得する。ローダは利用しているプラットフォームごとに様々な定義がある。例えばブラウザではHTML specで決められている。
ブラウザなら、 <script type="module">
を読みにいく
ローダはまた、ロードされたモジュールをどうするのかをも決める。これはESMの ParseModule
や ModuleEvaluate
メソッドをローダが使って実現している
各ステップについて詳しく見ていく