Skip to content

ESモジュールのrequire()エラーを解決する方法

問題の概要

Node.jsで作業中に以下のエラーが発生することがあります:

error [ERR_REQUIRE_ESM]: require() of ES Module [...] is not supported. Instead change the require of index.js to a dynamic import() which is available in all CommonJS modules

このエラーは、ESモジュール(ESM)としてのみ提供されているパッケージを、CommonJSのrequire()構文でインポートしようとした場合に発生します。Node.jsの最新バージョンでは、多くのパッケージがESモジュールに移行しているため、従来のrequire()ではインポートできなくなっています。

解決方法

方法1: 動的インポートを使用する(推奨)

ESモジュールをCommonJS環境で使用する最も簡単な方法は、動的インポートを使用することです:

javascript
// 従来の require() の代わりに:
const fetch = require('node-fetch');

// 動的インポートを使用:
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

エラーハンドリングを行う場合は、非同期関数内で使用します:

javascript
(async () => {
  try {
    const fetchModule = await import('node-fetch');
    const fetch = fetchModule.default;
    // ここにfetchを使用するコードを記述
  } catch (error) {
    console.error('モジュールの読み込みに失敗しました:', error);
  }
})();

方法2: パッケージのバージョンをダウングレードする

一時的な解決策として、ESMサポート前のバージョンを使用する方法があります:

bash
# node-fetchの場合
npm install node-fetch@2.6.1

# または他のパッケージの場合、適切なバージョンを指定
npm install package-name@older-version

WARNING

この方法は一時的な解決策です。古いバージョンを使用すると、セキュリティ更新や新機能を利用できなくなる可能性があります。

方法3: プロジェクトをESモジュールに移行する

長期的な解決策として、プロジェクト全体をESモジュールに移行することを検討してください。

package.jsonに以下を追加:

json
{
  "type": "module"
}

require()をimportに変更:

javascript
// 変更前
const fs = require('fs');
const path = require('path');

// 変更後
import fs from 'fs';
import path from 'path';

方法4: .mjs拡張子を使用する

特定のファイルのみをESモジュールとして扱いたい場合は、ファイル拡張子を.mjsに変更します:

bash
# script.jsをscript.mjsにリネーム
mv script.js script.mjs

.mjsファイル内ではimport/export構文が使用できます。

よくあるシナリオと解決策

node-fetchの問題を解決する

javascript
// 問題のあるコード
const fetch = require('node-fetch');

// 解決策1: 動的インポート
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

// 解決策2: 代替パッケージの使用
// node-fetch-nativeなどの互換性パッケージをインストール

TypeScriptプロジェクトでの設定

TypeScriptを使用している場合、tsconfig.jsonを調整する必要があります:

json
{
  "compilerOptions": {
    "module": "commonjs" // または "nodenext" を "commonjs" に変更
  }
}

ベストプラクティス

  1. 将来性を考慮した選択: 動的インポートまたはESモジュールへの完全移行が推奨されます
  2. エラーハンドリング: 動的インポートを使用する場合は、適切なエラーハンドリングを実装してください
  3. パッケージの互換性: 使用するパッケージのドキュメントを確認し、ESMサポート状況を把握してください

トラブルシューティング

特定のパッケージで問題が発生した場合:

  1. エラーメッセージで問題のパッケージを特定
  2. パッケージのドキュメントでESMサポートを確認
  3. 適切な解決策を選択(動的インポート、バージョン変更、代替パッケージ)

INFO

Node.jsのESモジュールサポートはまだ進化中の機能です。プロジェクトの要件と互換性を考慮して適切なアプローチを選択してください。

以上の解決策を適用することで、ESモジュールに関するrequire()エラーを解決し、現代的なNode.js開発を続行できるようになります。