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

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


やりたいこと

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

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)