Node.js で ES Modules 記法を動かしてみる
ブラウザ上で JS を import
するための仕組みとして、ES Modules という仕組みができた。コレを Node.js 上でも動かせるということで、やってみた。
目次
- 前提条件
- ES Modules を有効にするための条件がある
- 必須 :
import
文にファイル拡張子を必ず書く - 必須 : 実行時に
--experimental-modules
フラグを付ける - ソースファイルの拡張子を
.mjs
にする場合 - ソースファイルの拡張子を
.js
にする場合 : さらに条件がある - 以上
前提条件
ES Modules を試すには、Node.js v12 以降が必要。今回は以下の環境で試してみた。
$ node -v
v12.16.1
$ npm -v
6.13.4
ES Modules を有効にするための条件がある
Node.js 上で ES Modules を有効にするためには、いくつかの条件がある。
必須 : import
文にファイル拡張子を必ず書く
ES Modules では import from
構文が使えるようになるが、拡張子の指定が必須である。
// example.mjs があったとして…
// ↓ コレは拡張子がないので NG
import example from './example';
// ↓ このように拡張子込みで書く
import example from './example.mjs';
必須 : 実行時に --experimental-modules
フラグを付ける
$ node index.mjs
のように実行しようとしても、ES Modules として解釈されない。
$ node --experimental-modules index.mjs
このようにオプションを入れる必要がある。オプションはファイル名より手前に入れないとダメらしい。
ソースファイルの拡張子を .mjs
にする場合
ソースファイルの拡張子を .js
ではなく .mjs
とする場合は、上の2つを対応すれば OK。
./mjs/index.mjs
import hello from './hello.mjs';
hello();
./mjs/hello.mjs
export default function hello() {
console.log('Hello');
}
- 実行
$ node --experimental-modules mjs/index.mjs
(node:50565) ExperimentalWarning: The ESM module loader is experimental.
Hello
package.json
は別になくても動く。
ソースファイルの拡張子を .js
にする場合 : さらに条件がある
少しつまづいたのが、ソースファイルの拡張子が .js
のままな場合に、ES Modules を有効にする方法。
先ほどとほぼ同じコードで、import
部分の拡張子が .js
になっているパターンを用意する。
./js/index.js
import hello from './hello.js';
hello();
./js/hello.js
export default function hello() {
console.log('Hello');
}
package.json
は用意せず、次のように実行してみると、エラーが出てしまう。
$ node --experimental-modules js/index.js
(node:50599) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/Users/Neo/practice-esm/js/index.js:1
import hello from './hello.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
コレを回避するには、package.json
を用意し、"type": "module"
指定を加える必要がある。最低限以下でも動く。
$ echo '{ "type": "module" }' > package.json
$ node --experimental-modules js/index.js
(node:50651) ExperimentalWarning: The ESM module loader is experimental.
Hello
以上
Node.js 上で ES Modules を動かすのはまだまだ大変だなぁ…。コレもまだ「とりあえず動かせた」レベルだし…。