generated at
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年近く標準化にかかったけどそろそろ終わりそう

拡張子は.mjs

ESMをサポートするのは
主要なブラウザ(Firefox 60〜)

仕様策定
モジュールの読み込み
ESMのsyntax, JSのルール
例: this の扱い

ESMがどんな問題を解決して、他のモジュールシステムとどう違うのかを解説

モジュールが解決する問題
前提:JavaScriptにおいて、変数は関数のスコープ内に閉じ込められる
他の関数から参照されないので、よい

問題:変数を関数のスコープ外でどう共有すればいいか?
古来から行われてきた方法:グローバルスコープで共有する

jQueryはこうだった
jQueryがグローバルになかったらjQueryを期待するプラグインは実行時エラーになる
この方法の良くない点
この方法は、scrpitタグの順序が正しくなければいけないので、管理が複雑になる
どんな関数もグローバルのオブジェクトを利用でき、暗黙的な依存が発生する
悪意のあるコードは意図的にグローバルの変数を破壊できる

モジュールを使うと、この問題を解決できる
modulesのスコープに関数と変数を閉じ込める
関数スコープと違って変数を他のモジュールでも利用できる
import/exportで明示的に行うので、暗黙的な依存性はない

いま利用されているモジュールシステム
Node.jsが作ったCJS(歴史的にこちらのほうが古い)
JavaScriptの仕様に追加されたESM

ESモジュールのしくみ
ESMをロードするとmodule instanceができる
モジュールを使って開発するのは、依存性グラフをつくっているのと同じ
import文はブラウザやNodeがどのファイルを読めばいいのか指示する。このためブラウザはエントリポイントから入ってimport文をたどってすべてのファイルを見つけることができる
ファイルはそのままブラウザで使えるわけではない。いったんModule Recordというデータ構造に変換される
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 メソッドをローダが使って実現している
PuppeteerがJS engineを操作するようなもの

各ステップについて詳しく見ていく