blog.euxn.me

Node v9 でフラグ付きで ES Modules の importexport 構文を使用する

2017-11-10 Fri.

※ 03/22 追記 Node v10 での実装についてより詳細な内容が @about_hiroppy さんによって書かれていますので現在はそちらをご参考ください。 Node.js と ECMAScript Modules


Node v9 (実際には v8 系の後半から実装されていたようですが)では、フラグ付きで ES Modules の解釈ができるようになっています。 import/export 双方とも .mjs となっている必要があるようです。

index.mjs
1import Messanger from './messanger'
2
3Messanger.esm()
messanger.mjs
1export default class Messanger {
2 static esm() {
3 console.log('Hello ES Modules!')
4 }
5}
1$ node --experimental-modules index.mjs
2(node:8348) ExperimentalWarning: The ESM module loader is experimental.
3Hello ES Modules!

.mjs 拡張子で CommonJS を記述すると module が見つからずエラーとなるため、 CJS のファイルの拡張子は .js にする必要があります。 CommonJS 形式で記述されている( = 現行の node.js ライブラリ)の場合、 named import ができないため、以下のような記載はエラーになります。

messanger.js
1module.exports = class Messanger {
2 static esm() {
3 console.log('Hello ES Modules!')
4 }
5}
6module.exports.cjs = function() {
7 console.log('Hello CommonJS!')
8}
index.mjs
1import Messanger, { cjs } from './messanger' //=> SyntaxError: The requested module does not provide an export named 'cjs'

なので、以下のように使います。

index.mjs
1import Messanger from './messanger'
2const { cjs } = Messanger
3
4cjs() //=> Hello CommonJS!

or

index.mjs
1import Messanger from './messanger'
2
3Messanger.cjs() //=> Hello CommonJS!
4Messanger.esm() //=> Hello ES Modules!

後者だと呼び出し上、 Messanger の static メソッドと見分けがつかなくなるため、前者の方が良さそうに感じます。 数年後、ES Modules が標準になればライブラリ群も ES Modules でロード可能になるだろうと思うので、それまではライブラリ等の .js の named import 不可については意識していく必要がありそうです。


参考: Node.js の ES Modules サポートの現状確認と備え

Other Works
2024-12-01 Sun.
OpenAPI Spec を出力できる DSL、TypeSpec の実践例
- ドワンゴ教育サービス開発者ブログ

2024-11-16 Sat.
型付き API リクエストを実現するいくつかの手法とその選択
- TSKaigi Kansai 2024

2024-09-10 Tue.
corepack が標準同梱じゃなくなる未来、 mise でパッケージマネージャを管理する
- Zenn

2024-09-10 Tue.
言語環境の管理は *env や *vm を超えて、 mise へ
- Zenn

2024-06-28 Fri.
TypeSpec を使い倒してる
- Kyoto.js 22

2024-05-11 Sat.
Powerfully Typed TypeScript
- TSKaigi 2024

2024-05-10 Fri.
pnpm の node_modules を探検して理解しよう
- ドワンゴ教育サービス開発者ブログ

2024-03-17 Sun.
neverthrow で局所的に Result 型を使い、 try-catch より安全に記述する
- Zenn

2023-12-20 Wed.
レガシーブラウザ向けのビルドオプションを剪定する
- ドワンゴ教育サービス開発者ブログ

2023-05-26 Fri.
Next.js で dynamic import を使い Client だけで動かす Component を実現する
- Zenn

2023-05-02 Tue.
Node.js でファイル名から拡張子を取り除く/取り出すために path.parse を使う
- Zenn

2023-02-27 Mon.
WSL2 で外部からアクセス可能にするために bridge mode を有効にする
- Zenn

2023-01-26 Thu.
init.vim & dein から init.lua & lazy.nvim へ、シンプル設定で移行した
- Zenn

2023-01-13 Fri.
kindle の本をブクログ形式の csv でエクスポートする@2023初春
- Zenn

2023-01-10 Tue.
自宅サーバの移設に際して docker から nerdctl に移行した
- Zenn

2023-01-10 Tue.
自宅サーバを rootless に移行した際のトラブル対応
- Zenn

2021-11-11 Thu.
並列実行した Promise で throw されても全てハンドルしたいときの方法(allSettled, finally, etc...)
- Zenn