Vite: ビルド後にCJSモジュールで.defaultが必要になる
Viteで開発時は動作するが本番ビルド後に.defaultアクセスが必要になる問題
概要
Viteで開発サーバー使用時は正常に動作するが、本番ビルド後にCommonJSモジュールのmodule.exportsで公開された値にアクセスする際、.defaultが必要になる問題です。開発と本番でモジュール解決の挙動が異なることが原因です。
エラーメッセージ
Uncaught TypeError: Cannot read properties of undefined (reading 'xxx')
または、Reactの場合:
Minified React error #130: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
原因
- 開発時と本番時のモジュール解決の違い: 開発時はesbuildがCJSをESMに変換し自動的に
.defaultを処理するが、本番ビルドではRollupが異なる方法で処理する - CJSモジュールの
module.exports: CommonJSのmodule.exports = xxxはESMのexport defaultと完全に互換ではない - interop処理の差異: esbuild(開発)とRollup(本番)でCJS/ESM interopの実装が異なる
解決策
1. 明示的に.defaultを使用
| |
2. vite.config.jsで設定
| |
3. optimizeDepsで事前バンドル
| |
4. 名前付きインポートを使用
| |
5. 動的インポートでdefaultを取得
| |
6. ライブラリをESM版に置き換え
| |
7. Rollupプラグインで対応
| |
よくある間違い
- 開発環境でのみテストして本番ビルドを確認しない
- すべてのCJSライブラリが同じ挙動だと仮定する
module.exports = xxxとmodule.exports.default = xxxを混同する
関連エラー
参考リンク
JavaScript の他のエラー
この記事は役に立ちましたか?