何はともあれ
まずはこれとこれを見てください。公式の一次ソースです。3行で。
.js
はES Modulesとして扱われるよ- import時に拡張子の指定が必須になるよ
- でもこれまでとの互換性も確保するよ
.js
はES Modulesとして扱われるよ
今までは拡張子
.js
はCommonJSで、ES Modulesでは.mjs
という別の拡張子が必要でした。
しかし、今後はES Modules形式が一般的になることが容易に予想されます。
そうなったときでもES Modulesを使う場合は拡張子を
.mjs
にしなくてはいけないのか?という話。もちろん好ましくはないので、Node.js v12からは
.js
がCommonJSではなくES Modules形式として扱われるようになります。そして新たな拡張子
.cjs
が導入されました。この拡張子がついているファイルはCommonJSとして扱われます。ただし、いきなり変えてしまうと世界中が大混乱に陥るので、この挙動はパッケージ単位で設定可能で、デフォルトはCommonJSとして扱われます。
具体的には、
package.json
に以下のような記述があるとES Modules形式として扱われます。{ "type": "module" }この指定がない、あるいは
"type": "commonjs"
が指定されている場合は従来どおり.js
はCommonJSとして扱われます。この挙動はパッケージごとに指定可能です。
具体的には、ロードされたファイルと同じディレクトリにある
package.json
を探し、なければ親ディレクトリを順にたどって最初に見つかったpackage.json
の設定が適用されます。拡張子が必須になるよ
今まではES Modules形式でモジュールをロードするとき、拡張子が省略可能でした。例えば
module.mjs
というモジュールがあった場合、以下のどちらの形式でも指定可能でした。
import "module.mjs"; import "module";さらに、
module/index.mjs
というモジュールは以下のどれでも指定可能でした。
import "module/index.mjs"; import "module/index"; import "module";でも、ブラウザの
script
タグでロードするときは拡張子が必須です。拡張子を勝手に補完してくれたり、index.mjs
を補完してくれたりということはありません。ネットワーク経由のパフォーマンスを考えれば当然ではあります。
Node.js v12からは、挙動をブラウザに合わせることにしました。
つまり拡張子や
index.mjs
を省略することはできません。ちなみにこの挙動はES Modulesにのみ適用されるので、CommonJSではこれまで通り省略できます。
推測ですが、ES Modules形式はまだ実験段階の機能で使っている人はまだ少なく、最新情報をキャッチアップしている人が使っているから挙動を変えても大きな混乱はないと判断したんじゃないかと思います。
CommonJSは現状ほとんどの人が使っている&拡張子を省略している人が多いので、挙動を変えたら大混乱に陥るだろうという判断で現状のまま残したのではないかと。
とはいえ、互換性を考えてES Modules形式でも今までどおり拡張子を省略できるオプションもあります。コマンドラインで
--es-module-specifier-resolution=node
というオプションをつけてください。注意点として、これは実行するファイル全てに適用されるので、上で書いた
さらに詳しく
以上のような内容を10/25開催予定の関西Node学園 8時限目で話します。当日はもう少し細かい実践的な内容も話す予定です。
0 件のコメント:
コメントを投稿