Nodev12の新しいECMAScriptモジュールの概要
###はじめにReactやAngularなどの一般的なJavaScriptフロントエンドフレームワークに精通している場合、ECMAScriptの概念はまったく新しいものではありません。 ESモジュールには import
と export
フロントエンドフレームワークでよく見られる構文。 **ノードはに依存するCommonJSを使用します require()
輸入用。 これで、Nodeでインポートとエクスポートを使用できるようになりました。 require()
. 新しいNodev12リリースに付属しているのはそれだけではありません。期待できるすべての新しいクールな機能について話しましょう。
新しいESモジュール
これまで、以前のNodeリリースには、ECMAScriptモジュールの実験的なサポートが付属していました。 このサポートは --experimental-modules
フラグはまだありますが、前回のリリース以降、多くのことが起こっており、次のリリースに満足しています。 前回のリリースから提起された懸念事項とフィードバックの一部が実行され、次のリリースで実現されることを私たちは知っています。
Node.jsがインポートおよびエクスポート構文を使用する方法を提供する必要があるという優れたフィードバック .js
ファイル。 新しいで --experimental-modules
、これには2つの方法があります。
- 設定
“type” : “module”
のpackage.json
// package.json
{
"type": "module"
}
これは、Node.jsにすべてを処理するように指示します .js
ESモジュールとしてプロジェクト内のファイル。 モジュールとして扱いたくないCommonJSファイルがまだある場合は、次のように名前を変更できます。 .cjs
ファイル拡張子。Node.jsにCommonJSとして明示的に解析するように指示します。 または、すべてのCommonJSファイルを以下を含むサブフォルダーに配置することもできます。 package.json
とファイル "type":"commonjs"
、その下ですべて .js
ファイルはCommonJSとして扱われます。
最も近い親のpackage.jsonファイルに
type
フィールド、または含む"type": "commonjs"
、extensionlessおよび.jsファイルはCommonJSとして扱われます。 ボリュームルートに到達し、package.jsonが見つからない場合、Node.jsはデフォルトのpackage.jsonを使用しません。"type" field.import
最も近い親package.jsonにが含まれている場合、.jsおよび拡張子のないファイルのステートメントはESモジュールとして扱われます"type": "module"
.
このタイプと拡張機能のスコープは、CSSの優先順位が機能する方法と考えることができます。これは、ツリーを子から親に至るまでカスケードします。
- 使用
--input-type flag
node --experimental-modules --input-type=module --eval \
"import { sep } from 'path'; console.log(sep);"
echo "import { sep } from 'path'; console.log(sep);" | \
node --experimental-modules --input-type=module
インポートおよびエクスポート構文を使用する2番目の方法は、 --input-type=module
文字列入力を実行するには(経由 --eval
, --print
、 また STDIN
)ESモジュールとして。 The --input-type
フラグはどちらでもかまいません --input-type=module
また --input-type=commonjs
. この場合、CommonJSではなくモジュールに設定しているため、より早くなります。
より期待されるWIP機能
Node.jsモジュールチームがまだこれらの機能に取り組んでいることを考えると、既存の機能として正確に報告することはできません。 なんで? それらはまだ作業中であるため、おそらくすべてが変更される可能性がありますが、それらが何であるか、およびそれらがどのように動作する可能性があるかについてはわかっています。
モジュールローダー
非常にWIP機能。 の最初の実装が --loader
APIは出荷されましたが、まだ作業中です。そのため、次のリリースで変更される可能性があります。
パッケージパスマップ
この機能はまだ出荷されていません。 これにより、モジュールのインポート方法が再定義され、特定の状況で冗長性の低いインポートが可能になります。
自動エントリポイントモジュールタイプの検出
この機能により、Nodeはプロジェクトに存在するモジュールのタイプを識別できるようになります。 出荷時に、Nodeは特定のモジュールがESモジュールであるかCommonJSモジュールであるかを知ることができます。
Node v12には他にも多くの新機能があります。Mediumのモジュールチームによる公式ブログ投稿で、お気軽に深く掘り下げてください。 それまでの間、Nodeにあるモジュールのタイプを詳しく見てみましょう。
ノード内のさまざまなタイプのモジュール
これはこの時点で明白に見えるかもしれませんが、私は経験を積んで、ほとんどの人がNodeにあるさまざまなタイプのモジュールを理解するのに苦労していることを理解するようになりました。 最近まで、Nodeで必要なのはCommonJS構文だけであることを考えると、混乱を招く人がいることは理解できます。
Nodeには2つのモジュールタイプがあります。
- CommonJSモジュールタイプ
- ESモジュールタイプ
###CommonJSモジュール
CommonJSモジュールは、Nodeに付属するデフォルトのモジュールです。 ESモジュールの開始前は、すべてのノードアプリケーションは、を使用するCommonJSモジュール構造で動作します。 require()
と module.exports
モジュールをプルしてエクスポートするための構文。 この例を考えてみましょう。
//src/main.js
var products = require('src/products'); // import module
ここでは、 products
モジュールを main.js
私たちのアプリの別のファイルからのファイル src
ディレクトリ。 先に進んで、現在のファイルのモジュールを自由に使用できます。 これはどのように可能ですか? なぜなら products
関数は、のエクスポートオブジェクトに設定されます src/products
CommonJS仕様に従ったファイル。
//src/products.js
exports = function(){
return response.get('all-products);
}
Node.jsの実装
Node.jsの実装は、上記のCommonJSで見たものとそれほど変わりません。 違いは、モジュールがホストファイルからエクスポートされる方法にあります。 CommonJSはモジュールをエクスポートしますが exports
変数、ノードモジュールは使用します module.exports
物体。
//src/products
function products(){
return response.get('all-products);
}
modules.exports = products;
CommonJSの実装と同様に、これは同期プロセスであり、ファイルはファイル内に表示される順序で次々にロードされます。
###ESモジュール
ESモジュールは、CommonJSモジュールシステムの改善と見なすことができます。 を使用するだけでモジュールをインポートおよびエクスポートする可能性を提供します import
と export
の代わりとしてのキーワード require
CommonJSで。 CommonJSとは異なり、ESモジュールは同期モードと非同期モードの両方の操作モードと互換性があります。
上記の前の例でCommonJSを使用して見た製品の例を考慮すると、次のようにESモジュールを使用してファイルをやり直すことができます。
//src/main.js
import products from 'src/products'
前に説明したように、 import
ステートメントは、モジュールを名前空間に取り込むために使用されます。 CommonJSのrequireの代替手段とほぼ同じように動作しますが、動的ではないため、ファイル内のどこでも使用できません。 繰り返しになりますが、このファイルはおそらくホストファイルからエクスポートされているため、ここで使用するためにインポートすることができました。
//src/products.js
export function products() {
return response.get('all-products);
}
The export
ここでのステートメントにより、別のファイルからこの関数にアクセスできるようになります。 簡単に言えば、機能を広く利用できるようにします。 この結果、静的アナライザーは、最終的にコードを実行する前に、ファイルをバンドルしながら最初に依存関係のツリーを構築します。 これは、ESモジュールを使用することの主な利点であると私は考えています。
過去のノードのESM
NodeのESモジュールの概念はまったく新しいものではなく、Node.js8.9.0がECMAScriptモジュールの実験的なサポートを出荷した2017年から利用可能になりました。これは、 --experimental-modules
国旗。
ただし、この時点まで、この機能は実験的な状態のままです。 理由? Node.jsコミュニティがそれを使用し、その設計に関する実用的なフィードバックを提供できるようにするため。 それ以来、多くのことが起こりました。 主要なブラウザがECMAScriptモジュール(ESモジュール)をサポートするようになりました <script type="module">
. ESモジュールソースを含むnpmパッケージが、ブラウザで使用できるようになりました。 <script type="module">
. インポートマップのサポート。これにより、ブラウザにNode.jsスタイルのパッケージ名が表示されます。 import
ステートメント、はChromeに登場します。 そして、他にもたくさんあります。
長い間待っていて、実験的なESM設計に関するフィードバックを受け取りました。また、ESモジュールが使用されているランタイムや環境が他にもあるため、Node.jsがこのESMJavaScript標準をサポートするのに今ほど良い時期はありません。 そしてこれが、モジュールチームがESモジュールをサポートするための新しい実装を発表した理由です。 彼らによると、それはNode.js 12の一部として出荷され、古いものに取って代わります --experimental-modules
同じフラグの背後にある実装。
nvmを使用してv12を使い始める
ESMの長期的なサポートを待つ間、nvmを使用してESMの操作と機能に慣れることができます。 nvmを使用すると、1台のマシンに複数のバージョンのノードをインストールし、必要に応じてそれらを切り替えることができます。
つまり、現在Node v6またはv10を実行しているバージョンが何であれ、最新バージョンまたは古いバージョンに切り替えて、現在のバージョンとファイルをそのままにして試してみることができます。
nvm をインストールし、それを使用してNodeバージョンを管理し、現在のバージョンにはまだ存在しない MichaelWanyoikeのさまざまな機能を試す方法について説明したいと思います。 ]は、Sitepointのこの投稿ですでに素晴らしい仕事をしています。 さまざまなOSSプラットフォームでnvmがどのように機能するかを知りたい場合は、投稿にアクセスしてください。
—experimental-modulesフラグを使用して、LTSまでのインポートをサポートします
この投稿で前述したように、ESモジュールはしばらく前から存在しており、LTSまで使用するには2つの方法があります。
node index.js --experimental-modules
node --experimental-modules index.js
残念ながら、最初の方法、つまり node index.js --experimental-modules
は機能しないため、ノードアプリケーションでESMインポートをサポートするには、上記の2番目のオプションを使用する必要があります。
動的インポートはどこにも行きません
動的インポートは、着信ESモジュールの実装による脅威にさらされていないことに注意してください。 このESMの時代以前は、動的インポートにより、アプリケーション内のさまざまな場所からモジュールを動的にインポートして使用することができました。
動的インポートが要求されたモジュールのモジュール名前空間オブジェクトのpromiseを返すことを考えると、次を使用することができます。 async/await
そしてその .then()
モジュールを非同期でロードできるようにするすべてのモジュール動作を処理するベースのコールバックスタイル。 これが私たち全員がそれを愛している理由であり、新しい実装でそれを失うことはないということを知っているのは良いニュースです。
JSONファイルのインポートはどうですか?
今のところ、JSONモジュールのインポートは、箱から出してすぐにはサポートされていません。 module
モード。 ただし、 commonjs
モードであり、CJSローダーを備えたローダーです。 とは言うものの、現在、JSONインポートが module
モード。 たとえば、現在、 WHATWG JSONモジュールは現在標準化されており、追加のフラグを含めることで実験的にサポートされています --experimental-json-modules
Node.jsを実行しているとき。
JSONインポートは、箱から出してすぐにサポートされますが commonjs
モード、 --experimental-json-modules
フラグが含まれています、両方 commonjs
と module
モードは新しい実験的なJSONローダーを使用します。
ただし、少し欠点があります。インポートされたJSONは、 default
、したがって、現在、名前付きエクスポートはサポートされていません。 実験的なJSONローダーが優先されるため commonjs
モードでも、重複を避けるために、CommonJSキャッシュに個別のキャッシュエントリが作成されます。 JSONモジュールがすでに同じパスからインポートされている場合、同じオブジェクトがCommonJSに返されます。 以下の例を考えてみましょう。
import productsConfif from './package.json';
これが実際に機能するには、更新する必要があります
node --experimental-modules index.js
に
node --experimental-modules --entry-type=module --experimental-json-modules index.js
が利用できないため、以前は失敗します --experimental-json-modules
.
最終的な考え
Node.jsv12に登場する新しいEcmaScriptモジュールについては多くの議論がありました。 この記事では、通常のCommonJSの代替手段と比較して、それが何を提供するかを理解するために、それを詳しく調べました。