node.jsでimport/exportで試そうとしてハマったのでメモ。
$ node -v
v11.4.0
import / export を使っているファイルの拡張子は.mjs
でないとエラー
// moduleA.js export const hi = (name) => `Hi ${name}. `; // main.js import {hi} from './moduleA.js'; console.log( hi('星宮いちご') );
$ node main.js SyntaxError: Unexpected token
ファイルが.mjs
でも--experimental-modules
オプションがないとエラー
// moduleA.mjs export const hi = (name) => `Hi ${name}. `; // main.mjs import {hi} from './moduleA.mjs'; console.log( hi('星宮いちご') );
$ node main.mjs SyntaxError: Unexpected identifier
👇 --experimental-modules
をつける
$ node --experimental-modules main.mjs
ExperimentalWarning: The ESM module loader is experimental.
Hi 星宮いちご
ExperimentalWarning: The ESM module loader is experimental.
ってワーニングが表示されるけどimport/exportできています。
--experimental-modules
オプションは実行するファイルより前にないとエラー
$ node main.mjs --experimental-modules
ExperimentalWarning: The ESM module loader is experimental.
SyntaxError: Unexpected identifier
module.exports
しているファイルは.js
でもOK
// moduleB.js module.exports = { name: 'ジョニー別府' }; // main.mjs import foo from './moduleB.js'; console.log(foo.name);
$ node --experimental-modules main.mjs
ExperimentalWarning: The ESM module loader is experimental.
ジョニー別府
module.exports
なファイルだけをインポートしてる場合でもインポートしてるファイルは.mjs
でないとエラー
// moduleB.js module.exports = { name: 'ジョニー別府' }; // main.js import foo from './moduleB.js'; console.log(foo.name);
$ node --experimental-modules main.js
ExperimentalWarning: The ESM module loader is experimental.
SyntaxError: Unexpected identifier
import する時拡張子は省略してもOK
// moduleA.mjs export const hi = (name) => `Hi ${name}. `; // moduleB.js module.exports = { name: 'ジョニー別府' }; // main.mjs import {hi} from './moduleA'; import foo from './moduleB'; console.log( hi('星宮いちご') ); console.log(foo.name);
$ node --experimental-modules main.mjs
ExperimentalWarning: The ESM module loader is experimental.
Hi 星宮いちご
ジョニー別府
import するファイルの拡張子を省略した場合は.mjs
の方が優先される
// moduleA.mjs export const hi = (name) => `Hi ${name}. `; // moduleB.js module.exports = { name: 'ジョニー別府' }; // moduleB.mjs export default { name: '涼川直人' }; // main.mjs import {hi} from './moduleA'; import foo from './moduleB'; console.log( hi('星宮いちご') ); console.log(foo.name);
$ node --experimental-modules main.mjs
ExperimentalWarning: The ESM module loader is experimental.
Hi 星宮いちご
涼川直人
まとめ
node.jsv11.4.0
現在でimport/exportを使う時は
- importしてるメインのファイルは
.mjs
にする - モジュール側も
export 〜
を使っている場合は拡張子を.mjs
にする --experimental-modules
オプションが必要- importは拡張子を省略してもOK。
mjs
>js
の順にファイルを探す
ということのようです。
The
--experimental-modules
flag can be used to enable features for loading ESM modules.
Once this has been set, files ending with.mjs
will be able to be loaded as ES Modules.node --experimental-modules my-app.mjs出典: ECMAScript Modules | Node.js v11.4.0 Documentation
お手軽にnodeでコマンドラインからimport/exportを試せると思ったら罠だった...
まだ言語仕様が決まりきってないのが理由っぽいですが、node.js側とJavaScript(ECMAScript)側とで同じ機能なのに違いが生まれるのあまり幸せにならなそう…というお気持ち
[参考]
- Node.js で ECMAScript Modules を使ってみました – Espresso & Onigiri
- ECMAScript Modules | Node.js v11.4.0 Documentation
- https://whatwg.github.io/loader/
- .mjs とは何か、またはモジュールベース JS とエコシステムの今後 | blog.jxck.io
- Native ES Modules in NodeJS: Status And Future Directions, Part I
- ES6におけるimport/exportメモ - <y>
いまどきのJSプログラマーのための Node.jsとReactアプリケーション開発テクニック
- 作者: クジラ飛行机
- 出版社/メーカー: ソシム
- 発売日: 2017/07/26
- メディア: 単行本
- この商品を含むブログを見る
- 作者: 天田士郎
- 発売日: 2016/12/26
- メディア: Kindle版
- この商品を含むブログを見る