LoginSignup
4
2

More than 5 years have passed since last update.

Node.js(CommonJS)からECMAScript Moduleを読み込む

Posted at

やりたいこと

Webアプリのbuild時にクライアントサイドの設定定義ファイル (ECMAScript Module形式) をビルドスクリプト (Node.jsのスクリプト、CommonJS) 内で読み込み、定義内容に応じた事前処理を実行したい。

フォルダ構成
project
  +- src               <- Reactのsrcフォルダ
  |   `- commons
  |        `- index.js <- このファイルが設定定義
  |
  `- scripts
      `- build.js      <- ビルド時の処理が書かれた Node.jsのスクリプト

問題点

  1. 通常の方法 (require) では CommonJS形式のスクリプトからECMAScript Module形式のファイルを呼び出すことはできない
  2. CommonJS形式のスクリプトではECMAScript Module形式の import/export は使用できない

CommonJSからECMAScript Moduleを取り込む方法

以下の手順を踏むと、 CommonJS から ECMAScript Module を取り込める

(1) ECMAScript Moduleの拡張子を .mjs とする

common.mjs
// ECMAScript Module
export const VERSION = '1.0.0';
export const config = {
  hoge: 'fuga',
  foo: 'bar',
};

(2) dynamic import を使用してimportする

index.js
// CommonJS
async function main() {
  // dynamic import
  const { config } = await import('./common.mjs');
  console.log(config);
}

main()
  .then(() => { console.log('done!'); })
  .catch((err) => { console.error(err); });

(3) nodeコマンドに --experimental-modulesフラグを指定する

$ node --experimental-modules index.js
(node:22431) ExperimentalWarning: The ESM module loader is experimental.
{ hoge: 'fuga', foo: 'bar' }
done!

まとめ

build.js の冒頭で src/commons/index.jsscripts/common.mjs にコピーし、そのファイルをimportすることでやりたいことが実現できた。

build.js
const path = require('path');
const fs = require('fs-extra');

async function main() {
  // 設定定義ファイル
  const commonFile = path.resolve(__dirname, '../src/commons/index.js');
  // .mjsファイル
  const commonMjs = path.resolve(__dirname, './common.mjs');
  // ファイルをコピー
  await fs.copyFile(commonFile, commonMjs);
  // dynamic import
  const { config } = await import(commonMjs);

  // ...以降ビルド処理をゴニョゴニョ...
}

main()
  .then(() => { console.log('done!'); })
  .catch((err) => { console.error(err); });

参考

Node.jsとECMAScript Modules - 技術探し
https://blog.hiroppy.me/entry/nodejs-esm

ECMAScript Modules | Node.js v11.0.0 Documentation
https://nodejs.org/api/esm.html

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2