2017-11-10 Fri.
※ 03/22 追記
Node v10 での実装についてより詳細な内容が @about_hiroppy さんによって書かれていますので現在はそちらをご参考ください。
Node.js と ECMAScript Modules
Node v9 (実際には v8 系の後半から実装されていたようですが)では、フラグ付きで ES Modules の解釈ができるようになっています。
import/export 双方とも .mjs
となっている必要があるようです。
1import Messanger from './messanger'
2
3Messanger.esm()
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 ができないため、以下のような記載はエラーになります。
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}
1import Messanger, { cjs } from './messanger' //=> SyntaxError: The requested module does not provide an export named 'cjs'
なので、以下のように使います。
1import Messanger from './messanger'
2const { cjs } = Messanger
3
4cjs() //=> Hello CommonJS!
or
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 サポートの現状確認と備え