モジュール読み込みエラー「ambiguous indirect export: default」の解決法
問題の概要
Vue.js 3などJavaScriptプロジェクトで、カスタムクラスや外部ライブラリをインポートする際に、以下のエラーが発生します:
SyntaxError: ambiguous indirect export: default
このエラーが発生する典型的なコード例:
// クラス定義ファイル(formValidatorClass.js)
export class FormValidator {
// ...
}
// Vueファイルでのインポート
import FormValidation from "../classes/formValidationClass";
エラー原因は、モジュールのエクスポート形式とインポート形式の不一致です。ESモジュール(ESM)とCommonJS(CJS)の仕様の違いや、不適切なインポート構文によって発生します。
根本原因と解決方法
ケース1:名前付きエクスポートとデフォルトインポートの不一致(最も一般的)
問題コード
// エクスポート側(名前付きエクスポート)
export class FormValidator {}
// インポート側(デフォルトインポート)
import FormValidation from '../classes/formValidationClass';
解決方法
名前付きエクスポートを{}
でインポート:
import { FormValidator } from "../classes/formValidatorClass";
// 別名でインポートする場合
import { FormValidator as FormValidation } from "../classes/formValidatorClass";
デフォルトエクスポートとの違い
export class Foo
: 名前付きエクスポート →import { Foo }
でインポートexport default class Foo
: デフォルトエクスポート →import Foo
でインポート
ケース2:デフォルトエクスポートと名前付きインポートの不一致
問題コード
// エクスポート側(デフォルトエクスポート)
export default class FormValidator {}
// インポート側(名前付きインポート)
import { FormValidator } from '../classes/formValidatorClass';
解決方法
デフォルトインポート構文を使用:
import FormValidator from "../classes/formValidatorClass";
ケース3:ESモジュールとCommonJSの混在問題(ライブラリ使用時)
外部ライブラリ(例:axios)使用時に発生するケース:
// CommonJSモジュールをES構文でインポートしようとするとエラー
import axios from "axios";
ブラウザごとのエラーメッセージ差異
- Firefox:
ambiguous indirect export: default
- Chrome:
The requested module does not provide an export named 'default'
解決方法1:ライブラリのアップグレード
ライブラリ側がESモジュールに対応しているバージョンに更新:
npm install axios@latest
解決方法2:互換性のあるインポート構文
import * as axiosModule from "axios";
const axios = axiosModule.default;
その他の原因と対処法
キャッシュ問題
ブラウザまたはバンドラーのキャッシュが原因の場合:
# Viteの場合
rm -rf node_modules/.vite
ツール固有の問題(Vite/WebStorm)
ファイル拡張子関連の問題
- TypeScript(.ts)とJavaScript(.js)ファイルが混在する場合、誤って.jsファイルが読み込まれる
- 対策:ファイル削除または
vite.config.js
で明示的に対象指定
ビルド設定の問題(モノレポ構成など)
{
"main": "./dist/index.js",
// ESM対応の追加
"module": "./dist/index.mjs",
"scripts": {
"build": "tsup src/index.ts --format esm,cjs"
}
}
型インポートの誤り(TypeScript)
型をimport type
で明示的にインポート:
import type { TUser } from '../models/Users/Users';
import { TUser } from '../models/Users/Users'; // 型のみのインポートは不可
解決フローチャート
実践的アドバイス
一貫したエクスポート方式の採用:
- チームで「名前付きエクスポートのみ」か「デフォルトエクスポート中心か」を統一
自動インポート機能に注意:
javascript// IDEが自動生成するインポートを常に確認 import { Foo } from "./old-module"; // リファクタリング後はエラー
最新ツールの活用:
json{ "type": "module" // ESモジュールを明示 }
エラーの再現確認手順:
bash# クリーンインストールで再現するか確認 rm -rf node_modules package-lock.json npm install
危険な回避策
エラーの根本解決せずに以下のようなコードを使用しないでください:
// アンチパターン例
const module = await import("./module.js");
まとめ
「ambiguous indirect export」エラーはモジュールシステムの整合性の問題です。解決には以下を徹底してください:
- エクスポート形式(名前付き/デフォルト)の確認
- 対応するインポート構文の使用
- ライブラリのESモジュール対応状況の確認
- 開発環境のキャッシュクリア
現代フロントエンド開発では、ESモジュールを基盤にした構成が主流です。利用するライブラリのモジュール形式を理解し、プロジェクト全体で整合性を保つことが重要です。