NodeJSは、インポート/エクスポートes6(es2015)モジュールのサポートを計画しています


275

私はこれについて明確な答えがないままインターネット全体を調べてきました。

現在、NodeJSはCommonJS構文のみを使用してモジュールをロードしています。標準のES2015モジュール構文を本当に使用したい場合は、事前にトランスパイルするか、実行時に外部モジュールローダーを使用する必要があります。

現在、私はこれらの2つの方法のいずれかを使用するのにあまり前向きではありません。NodeJSのメンテナはES2015モジュールをサポートする計画を立てているのでしょうか?これについてのヒントはまったく見つかりませんでした。

現在、NodeJS 6.xはES2015の機能の96%をサポートしていると主張していますが、モジュールへの参照はありません(NodeJS ES2105サポートリンク)。

NodeJSがすぐにこれらのモジュールをすぐにサポートするかどうか知っていますか?


2
のグーグルでnode es2015 modulesは、上位結果の1つとしてgithub.com/nodejs/node/wiki/ES6-Module-Detection-in-Nodeが表示されます。
フェリックスクリング2016年

6
個人的に私はこの質問を「あまりにもローカライズされている」として終了するよう投票しますが、その終了理由はもう存在しません。Nodeが明日ES6モジュールを実装することに成功したとしましょう。質問はもう関係ないので、削除しますか?または、少なくとも更新しますか?古くなっている、または「すぐに」更新する必要があることをすでに知っている場合、SOに適した質問だとは思いません。しかし、それはちょうど私の意見だと:)私のためokです反対に、考える他の人があるように思われる(FWIWは、それ自体での質問はもちろん重要で興味深いのです)
フェリックスクリング

2
でも、スタックユニバースにこのような質問ができる場所があればいいのに。技術的にはここには収まらないかもしれませんが、それが本当に「意見に基づく」ものであることに私が同意するかどうかはわかりません。OPは特定の質問に対する特定の回答を探していますが、(ある時点で)古くなります。
Wonko the Sane 2017

5
この質問の別の言い回し:「ES6モジュールのnode.jsサポートの状態は?」多くのSOの質問に対する答えは、技術の進化に伴い変化します。私もここに着くまで、答えを見つけるのに苦労しました。
ジョーラップ2017

4
@FelixKling質問を締めくくるのは非常に間違った判断だったと思います。これは問題であり、これまで211人が投票するほど問題があることが判明したためです。
ムハンマドウメール2018年

回答:


302

ノード13.2.0以上

NodeJS 13.2.0はフラグなしのESモジュールをサポートするようになりました🎉ただし、実装はまだ実験的としてマークされているので、注意して本稼働で使用してください。

13.2.0でESMサポートを有効にするには、以下をに追加しますpackage.json

{
  "type": "module"
}

すべては.js.mjs(または拡張子のないファイル)ESMとして扱われます。

package.jsonオプトイン全体以外にもさまざまなオプションがあり、すべて13.2.0ドキュメントで詳しく説明されています。

ノード13.1.0以下

Nodeの古いバージョンをまだ使用している人は、NodeJSのES Modules Specの本番環境に対応した実装であるesmモジュールローダーを試してみるとよいでしょう。

node -r esm main.js

詳細なアップデート...

2019年4月23日

ESモジュールの検出方法を変更するために最近上陸したPR:https : //github.com/nodejs/node/pull/26745

まだ--experimental-modulesフラグの後ろにありますが、モジュールのロード方法に大きな変更があります:

  • package.typeそのいずれかになりますmodulecommonjs
    • type: "commonjs"
      • .js commonjsとして解析されます
      • 拡張機能なしのエントリポイントのデフォルトはcommonjsです
    • type: "module"
      • .js esmとして解析されます
      • デフォルトではJSONまたはネイティブモジュールのロードをサポートしていません
      • 拡張子のないエントリポイントのデフォルトはesmです
  • --type=[mode]エントリポイントのタイプを設定できます。package.typeエントリポイントをオーバーライドします。
  • 新しいファイル拡張子.cjs
    • これは、moduleモードでのcommonjsのインポートをサポートするためのものです。
    • これはesmローダーにのみ存在し、commonjsローダーは変更されませんが、完全なファイルパスを使用すると、拡張機能は古いローダーで機能します。
  • --es-module-specifier-resolution=[type]
    • オプションはexplicit(デフォルト)およびnode
    • デフォルトでは、ローダーはインポートでオプションの拡張を許可しません。モジュールのパスには、拡張がある場合はそれを含める必要があります
    • デフォルトでは、ローダーはインデックスファイルがあるディレクトリのインポートを許可しません
    • 開発者--es-module-specifier-resolution=nodeはcommonjs指定子解決アルゴリズムを有効にするために使用できます
    • これは「機能」ではなく、実験のための実装です。フラグが削除される前に変更されることが予想されます
  • --experimental-json-loader
    • jsonをインポートする唯一の方法 "type": "module"
    • 有効にするimport 'thing.json'と、モードに関係なくすべてが実験的ローダーを通過します
    • whatwg / html#4315に基づく
  • を使用package.mainして、モジュールのエントリポイントを設定できます。
    • mainで使用されるファイル拡張子は、モジュールのタイプに基づいて解決されます

2019年1月17日

ノード11.6.0は、フラグの後ろにまだESモジュールを実験的としてリストします。

2017年9月13日

NodeJS 8.5.0がリリースされ、フラグの後ろのmjsファイルがサポートされました。

node --experimental-modules index.mjs

この計画は、v10.0 LTSリリースのフラグを削除することです。

-古い情報。歴史的な目的のためにここに保管しました-

2017年9月8日

NodeJSマスターブランチが更新され、ESMモジュールの初期サポートが追加されました:https :
//github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

これは最新の夜間に利用可能になるはずです(これはnvm介してインストールして、既存のインストールと一緒に実行できます):https : //nodejs.org/download/nightly/

--experimental-modulesフラグの後ろで有効化:

package.json

{
  "name": "testing-mjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs" <-- Set this to be an mjs file
}

次に実行します:

node --experimental-modules .

2017年2月:

https://medium.com/@jasnell/an-update-on-es6-modules-in-node-js-42c958b890c#.6ye7mtn37

NodeJSの連中は、ファイル拡張子を使用することが最も悪い解決策であると判断しました.mjs。これからの要点は次のとおりです。

つまり、2つのファイルfoo.jsとを指定するとbar.mjs、使用import * from 'foo'するfoo.jsとCommonJS としてimport * from 'bar' 扱わbar.mjsれ、ES6モジュールとして扱われます

そしてタイムラインについては...

現時点では、Node.jsがES6モジュールのサポート可能な実装の作業を開始する前に、ES6および仮想マシン側で発生する必要のある仕様および実装の問題がまだいくつかあります。作業は進行中ですが、しばらく時間がかかります—現在、少なくとも 1年程度は検討中です。

2016年10月:

Node.JSの開発者の1人が最近TC-39ミーティングに参加し、Node.JSの実装に対するブロッカーに関する優れた記事を書きました:

https://hackernoon.com/node-js-tc-39-and-modules-a1118aecf95e

これからの基本的なポイントは次のとおりです。

  • ESモジュールは静的に分析され、CommonJSが評価されます
  • CommonJSモジュールでは、モンキーパッチエクスポートが可能ですが、ESモジュールでは現在、
  • なんらかのユーザー入力なしにESモジュールとCommonJSを検出することは困難ですが、彼らは試みています。
  • *.mjs ユーザーが入力しなくてもESモジュールを正確に検出できない限り、最も可能性の高い解決策のようです

-元の回答-

これはかなり長い間ホットポテトでした。つまり、Nodeは最終的にモジュールのインポート/エクスポートのためのES2015構文をサポートします- モジュールをロードするための仕様が完成し、合意されたときに最も可能性が高くなります。

NodeJSを支えているものの概要を次に示します。基本的に、彼らは新しい仕様が主に条件付きの同期ロードであるNodeと、主に非同期であるHTMLでも機能することを確認する必要があります。

今のところ誰も確かなことはわかりませんが、レガシーコードを維持しながらimport/export、NodeがSystem.import動的ロードの新しいものに加えて静的ロードをサポートすることを想像しrequireます。

Nodeがこれを実現する方法に関するいくつかの提案を以下に示します。


38
.mjs拡張子について:We have affectionately called these “Michael Jackson Script” files in the past。JSトーク中に誰かがポップアーティストについて話しているのを聞いた場合に備えて。
Jeewes

1
インポートの構文を変更するだけでは不十分な理由がわかりません。esをインポートするための1つの構文(「正しい」構文)とcjsをインポートするための構文?言い換えれば、foo.jsとbar.jsの2つのファイルが与えられた場合、 import * from 'foo'foo.jsはCommonJS import * as bar from 'bar'がbar.jsをES6モジュールとして扱うので、foo.jsを扱います。
コーリーアリックス2017年

1
@CoreyAlix構文は通常、環境をサポートするために変更されません。結局のところ、これは本当にノードにのみ影響します。また、構文は少し直感的ではありません。提案された構文でエクスポートにアクセスするにはどうすればよいですか?
CodingIntrigue 2017年

明確に言うと、それは「私の」提案ではなく、typescriptがすでに行っていることをコピーしています。質問に答えるには、 "bar"を使用してエクスポートにアクセスします。bar.foobar()import {foo as Foo} from "./foo"は、ES6モジュールを識別するメカニズムです。var Foo = require(“ ./ foo”)は、CJSモジュールを識別するためのメカニズムです。Typescriptでは、commonjs出力は次のようになります。var mod1_1 = require( "./ mod1"); exports.mod1 = mod1; ES6の出力は次のようになります。import {mod1} from“ ./mod1”; エクスポート{mod1}
Corey Alix

1
この回答に対するノード10の更新で本当に興味深いと思います。フィーチャーはカットを作りましたか、それともフラグの後ろにありますか?
18
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.