Node.jsのECMAScriptモジュール(ESM)の現在のサポート状況:
- 実験的なESMサポートは、2017年9月12日にNode.js 8.5.0で追加されました。
- その後、Node.jsの技術運営委員会は、 モジュールチームを担当するチームを編成し、今後の(実験的ではない)リリースの欠落部分の設計を支援しました。 このチームは、さまざまなWeb開発業界(フロントエンド、バックエンド、JSエンジンなど)の人々で構成されています。
10月、モジュールチームは「新しいモジュールの実装計画」を公開しました。 この投稿では、内容について説明します。
段階
プロセスは3つのフェーズに分かれています。
- フェーズ1:「最小限の」コア-可能な限り最小限で確実な基本的なルールと機能のセットを作成します。
- フェーズ2以降:カーネルに基づいてより複雑な機能を作成します。
最小限のコアが将来の作業の基礎になります。 新しいデザインは、同様の機能を獲得するとすぐに、現在の実験的な実装を置き換えます。
フェーズ1:Node.jsの最小コアESMサポート
モジュール識別子の簡素化
Modules Teamの目標の1つは、 「ブラウザーの同等性」を達成することです。Node.jsは、ブラウザーにできるだけ近づける必要があります。 カーネルは、モジュール識別子(モジュールを指すURL)の解析を簡素化することでこれを行います。
- 各モジュール識別子は、拡張子付きのファイル名で終わる必要があります。 それは
- 拡張機能は自動的に追加されません
- ディレクトリのインポートはサポートされていません(
dir/index.mjs
リダイレクトするか、package.json
main
フィールドを読み取ることにより)。
- ESモジュールは、組み込みのNode.jsモジュール(
path
など)をインポートできます。 前のルールの唯一の例外です。 - デフォルトでは、拡張子が
.mjs
ファイルのみが.mjs
れています(他の拡張子のステータスに関心がある場合は、フェーズ2を参照してください)。 したがって、インポートによって他のタイプのモジュールをimport
することはできません:CommonJSモジュール、JSONファイル、ネイティブモジュール。
重要なCommonJS機能をESモジュールに組み込む
- 現在のモジュールのURL(CommonJSの
__filename
類似): import.meta.url - ESモジュールの動的インポート
require()
CommonJSのrequire()
を介して利用可能):import()
互換性
- ESモジュールは、
createRequireFromPath()
介してCommonJSモジュールをインポートできます。 これは次のように機能します(たとえば、createRequireFromUrl()
関数などの短縮メソッドを作成する計画があります)。
import {createRequireFromPath as createRequire} from 'module'; import {fileURLToPath as fromPath} from 'url'; const require = createRequire(fromPath(import.meta.url)); const cjsModule = require('./cjs-module.js');
- CommonJSモジュールは、
import()
介してESモジュールをロードできます。
フェーズ2および将来の計画
- 第2フェーズでは、次のことを待っています。
-
'lodash'
などの「裸の」識別子のサポート。 ほとんどの場合、これには、これらの識別子を実際のパスにマッピングする何らかの方法が含まれます。 -
.mjs
以外の他のファイル拡張子のサポート。 これには、とりわけ、.js
ファイルでのESモジュールのサポートが含まれます。
-
- フェーズ3は、ユーザーがロジックをプラグインできる拡張ポイントを持つモジュールローダーに焦点を当てる可能性が最も高いでしょう。
Node.jsでESモジュールを使用できるのはいつですか?
- 旗の後ろ: 今すぐ利用可能
- 注意:動作は、上記のフェーズ1で説明した動作とまだ一致していません(Node.js 11.5.0以降)
- フラグなしで、フェーズ1に従って:モジュールチームは、できるだけ早くこれを可能にしようとしています。 Node.js 14(2020年4月)のフラグからモジュールがリリースされ、可能であれば以前のバージョンに移植されることを願っています。
よくある質問
- 新しい
.mjs
ファイル.mjs
が必要なのはなぜですか?
- ESM形式とCommonJS形式を区別する各決定には、長所と短所があります。 別の解像度を使用するのは良い選択肢のように思えます( 詳細 )。
- Node.jsがブラウザーのように動作するのはなぜですか?
- コードの再利用が可能になるためです。 たとえば、ブラウザとNode.jsの両方で機能するライブラリを作成するには
- また、コーディング中にバックエンドとフロントエンドの切り替えを容易にする必要があります。
- 互換性のためにこれらすべての制限があるのはなぜですか?
- ESモジュールとCommonJSモジュールの間には、構造(静的と動的)およびロード方法(非同期と同期)にかなりの違いがあります。 制約は、物事をシンプルに保つのに役立ちます-長期的に見れば、圧倒的多数はESモジュールになります。
- なぜそんなに長く続くのですか?
- ここには多くの利害関係者が関与しており、多くの異なるプラットフォームが関与しています(Node.js、npm、ブラウザー、JSエンジン、TypeScript、TC39など)。 どこでも動作するESモジュールを本当に手に入れたら、おそらく待つ価値があります、私見。
感謝の気持ち
この投稿に関するフィードバックを寄せてくれたMiles Borinsに感謝します。