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において、変数は関数のスコープ内に閉じ込められる
他の関数から参照されないので、よい
問題:変数を関数のスコープ外でどう共有すればいいか?
古来から行われてきた方法:グローバルスコープで共有する
https://gyazo.com/8c0e9def0198cb77331fff6f961f2cc5
jQueryがグローバルになかったらjQueryを期待するプラグインは実行時エラーになる
この方法の良くない点
この方法は、scrpitタグの順序が正しくなければいけないので、管理が複雑になる
どんな関数もグローバルのオブジェクトを利用でき、暗黙的な依存が発生する
悪意のあるコードは意図的にグローバルの変数を破壊できる
モジュールを使うと、この問題を解決できる
modulesのスコープに関数と変数を閉じ込める
https://gyazo.com/3aa9e497ffaebbff640f51c798b17140
関数スコープと違って変数を他のモジュールでも利用できる
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メソッドをローダが使って実現している
各ステップについて詳しく見ていく