MeWrite Docs

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.

原因

  1. 開発時と本番時のモジュール解決の違い: 開発時はesbuildがCJSをESMに変換し自動的に.defaultを処理するが、本番ビルドではRollupが異なる方法で処理する
  2. CJSモジュールのmodule.exports: CommonJSのmodule.exports = xxxはESMのexport defaultと完全に互換ではない
  3. interop処理の差異: esbuild(開発)とRollup(本番)でCJS/ESM interopの実装が異なる

解決策

1. 明示的に.defaultを使用

1
2
3
4
5
6
// Before(開発では動くが本番で壊れる)
import SomeComponent from 'some-cjs-library';

// After
import SomeComponentModule from 'some-cjs-library';
const SomeComponent = SomeComponentModule.default || SomeComponentModule;

2. vite.config.jsで設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    commonjsOptions: {
      transformMixedEsModules: true,
      // または特定のモジュールを指定
      include: [/node_modules/],
    },
  },
});

3. optimizeDepsで事前バンドル

1
2
3
4
5
6
// vite.config.js
export default defineConfig({
  optimizeDeps: {
    include: ['problematic-cjs-library'],
  },
});

4. 名前付きインポートを使用

1
2
// module.exports = { foo, bar } の場合
import { foo, bar } from 'some-cjs-library';

5. 動的インポートでdefaultを取得

1
2
const module = await import('some-cjs-library');
const SomeComponent = module.default;

6. ライブラリをESM版に置き換え

1
2
# ESMをサポートするバージョンや代替ライブラリを検討
npm install some-library@latest

7. Rollupプラグインで対応

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// vite.config.js
import commonjs from '@rollup/plugin-commonjs';

export default defineConfig({
  plugins: [
    commonjs({
      requireReturnsDefault: 'auto',
    }),
  ],
});

よくある間違い

  • 開発環境でのみテストして本番ビルドを確認しない
  • すべてのCJSライブラリが同じ挙動だと仮定する
  • module.exports = xxxmodule.exports.default = xxxを混同する

関連エラー

参考リンク

JavaScript の他のエラー

最終更新: 2025-12-13