Skip to content

モジュール読み込みエラー「ambiguous indirect export: default」の解決法

問題の概要

Vue.js 3などJavaScriptプロジェクトで、カスタムクラスや外部ライブラリをインポートする際に、以下のエラーが発生します:

js
SyntaxError: ambiguous indirect export: default

このエラーが発生する典型的なコード例:

javascript
// クラス定義ファイル(formValidatorClass.js)
export class FormValidator {
  // ...
}

// Vueファイルでのインポート
import FormValidation from "../classes/formValidationClass";

エラー原因は、モジュールのエクスポート形式とインポート形式の不一致です。ESモジュール(ESM)とCommonJS(CJS)の仕様の違いや、不適切なインポート構文によって発生します。

根本原因と解決方法

ケース1:名前付きエクスポートとデフォルトインポートの不一致(最も一般的)

問題コード

js
// エクスポート側(名前付きエクスポート)
export class FormValidator {}

// インポート側(デフォルトインポート)
import FormValidation from '../classes/formValidationClass';

解決方法

名前付きエクスポートを{}でインポート:

javascript
import { FormValidator } from "../classes/formValidatorClass";
javascript
// 別名でインポートする場合
import { FormValidator as FormValidation } from "../classes/formValidatorClass";

デフォルトエクスポートとの違い

  • export class Foo: 名前付きエクスポート → import { Foo } でインポート
  • export default class Foo: デフォルトエクスポート → import Foo でインポート

ケース2:デフォルトエクスポートと名前付きインポートの不一致

問題コード

js
// エクスポート側(デフォルトエクスポート)
export default class FormValidator {}

// インポート側(名前付きインポート)
import { FormValidator } from '../classes/formValidatorClass';

解決方法

デフォルトインポート構文を使用:

javascript
import FormValidator from "../classes/formValidatorClass";

ケース3:ESモジュールとCommonJSの混在問題(ライブラリ使用時)

外部ライブラリ(例:axios)使用時に発生するケース:

js
// CommonJSモジュールをES構文でインポートしようとするとエラー
import axios from "axios";

ブラウザごとのエラーメッセージ差異

  • Firefox: ambiguous indirect export: default
  • Chrome: The requested module does not provide an export named 'default'

解決方法1:ライブラリのアップグレード

ライブラリ側がESモジュールに対応しているバージョンに更新:

bash
npm install axios@latest

解決方法2:互換性のあるインポート構文

javascript
import * as axiosModule from "axios";
const axios = axiosModule.default;

その他の原因と対処法

キャッシュ問題

ブラウザまたはバンドラーのキャッシュが原因の場合:

bash
# Viteの場合
rm -rf node_modules/.vite

ツール固有の問題(Vite/WebStorm)

ファイル拡張子関連の問題
  • TypeScript(.ts)とJavaScript(.js)ファイルが混在する場合、誤って.jsファイルが読み込まれる
  • 対策:ファイル削除またはvite.config.jsで明示的に対象指定

ビルド設定の問題(モノレポ構成など)

json
{
  "main": "./dist/index.js",
  // ESM対応の追加
  "module": "./dist/index.mjs",
  "scripts": {
    "build": "tsup src/index.ts --format esm,cjs"
  }
}

型インポートの誤り(TypeScript)

型をimport typeで明示的にインポート:

typescript
import type { TUser } from '../models/Users/Users';
typescript
import { TUser } from '../models/Users/Users'; // 型のみのインポートは不可

解決フローチャート

実践的アドバイス

  1. 一貫したエクスポート方式の採用

    • チームで「名前付きエクスポートのみ」か「デフォルトエクスポート中心か」を統一
  2. 自動インポート機能に注意

    javascript
    // IDEが自動生成するインポートを常に確認
    import { Foo } from "./old-module"; // リファクタリング後はエラー
  3. 最新ツールの活用

    json
    {
      "type": "module" // ESモジュールを明示
    }
  4. エラーの再現確認手順

    bash
    # クリーンインストールで再現するか確認
    rm -rf node_modules package-lock.json
    npm install

危険な回避策

エラーの根本解決せずに以下のようなコードを使用しないでください:

js
// アンチパターン例
const module = await import("./module.js");

まとめ

「ambiguous indirect export」エラーはモジュールシステムの整合性の問題です。解決には以下を徹底してください:

  1. エクスポート形式(名前付き/デフォルト)の確認
  2. 対応するインポート構文の使用
  3. ライブラリのESモジュール対応状況の確認
  4. 開発環境のキャッシュクリア

現代フロントエンド開発では、ESモジュールを基盤にした構成が主流です。利用するライブラリのモジュール形式を理解し、プロジェクト全体で整合性を保つことが重要です。