Node.js

Node.js の開発版で ES モジュールローダーを試す

概要

2017年9月8日の Node.js 開発版から ES モジュールローダーを試すことができるようになりました。試験的な機能なので、スクリプトの実行時に --experimental-modules フラグを指定する必要があります。

公式マニュアル

Github の node/doc/api/esm.mdご参照ください。

NVS による開発版のインストール

開発版を手軽に試すには NVS (Node Version Swither) が手軽です。

nvs add nightly
nvs use nightly

正式な最新バージョンを導入するには次のコマンドを実行します。

nvs add latest
nvs use latest

モジュールをつくる

ES モジュールをつくってみましょう。拡張子を .mjs にする必要があります。

hello.mjs
const msg = "hello";

function hello() {
  console.log(msg);
}

export { msg, hello };

ES モジュールを読み込んで、実行するスクリプトの拡張子も .mjs にする必要があります。

main.mjs
import { msg, hello } from "./hello";

console.log(msg);
hello();

実行

スクリプトを実行してみましょう。

node --experimental-modules main.mjs

(node:49617) ExperimentalWarning: The ESM module loader is experimental.
hello
hello

実行するスクリプトの拡張子が .js の場合、次のようなエラーメッセージが表示されます。

node --experimental-modules main.js
/Users/masakielastic/test/esm-project/main.js:1
(function (exports, require, module, __filename, __dirname) { import { msg, hello } from "./hello";
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:564:28)
    at Object.Module._extensions..js (module.js:611:10)
    at Module.load (module.js:521:32)
    at tryModuleLoad (module.js:484:12)
    at Function.Module._load (module.js:476:3)
    at Function.Module.runMain (module.js:641:10)
    at startup (bootstrap_node.js:201:16)
    at bootstrap_node.js:626:3

読み込もうとするモジュールの拡張子が .js の場合、次のようなエラーメッセージが表示されます。

(node:49783) ExperimentalWarning: The ESM module loader is experimental.
SyntaxError: The requested module does not provide an export named 'msg'
    at checkComplete (internal/loader/ModuleJob.js:86:27)
    at moduleJob.linked.then (internal/loader/ModuleJob.js:69:11)
    at <anonymous>

標準モジュールを読み込む

url モジュールの URLSearchParams を試してみましょう。

client.mjs
import url from "url";

const params = new url.URLSearchParams();
params.append("msg", "hello world");

console.log(params.toString());
// msg=hello+world

記事の執筆時点では次の書き方はエラーになります。

import { URLSearchParams } from "url";

const params = new URLSearchParams();
console.log(params.toString());
// msg=hello+world

エラーメッセージは次のとおりです。

SyntaxError: The requested module does not provide an export named 'URLSearchParams'
    at checkComplete (internal/loader/ModuleJob.js:86:27)
    at moduleJob.linked.then (internal/loader/ModuleJob.js:69:11)
    at <anonymous>

開発環境における代替策

開発環境でモジュールローダーを手軽に試したい場合の代替案が複数あります。

@std/esm

Node v4 から ESM を利用できるようにするツールです。スクリプトの実行時に r オプションで読み込みます。

node -r @std/esm main.mjs

yarn で導入するには次のコマンドを実行できます。

yarn add --dev @std/esm

babel-node と babel-preset-env

babel-preset-env のおかげでトランスパイルするコードの量を最小限に抑えることができます。

package.json
{
  "babel": {
    "presets": [
      ["env", {"targets": { "node": "current" }}]
    ]
  }
}

Yarn による導入は次のとおりです。

yarn add --dev babel-cli babel-preset-env

スクリプトの実行に npx を使うことができます。

npx babel-node client.mjs

トランスパイルされたコードを見たいのであれば、babel コマンドを使います。

npx babel client.mjs