WebpackからViteへの移行:「ESMの壁」を突破し、モダンな開発体験を完全掌握する
こんにちは。現場でフロントエンドのアーキテクチャを設計しているエンジニアです。
Webpackの重厚なビルド時間に別れを告げ、Viteの爆速な開発サーバーに乗り換えようとしたとき、多くのチームが必ず直面する「ラスボス」がいます。それが「CommonJS (CJS) vs ESM (ECMAScript Modules) の非互換問題」です。
Webpackは「何でもあり」の混沌とした世界でしたが、Viteは「ESMネイティブ」という規律を重んじます。この規律を守らない古いライブラリを読み込もうとすると、コンソールには `Uncaught ReferenceError: exports is not defined` といった冷酷なエラーが突きつけられます。
今日は、この「ESMの壁」をスマートに突破し、レガシーな資産をモダンなビルド環境に融合させるための、実務的な戦略を授けましょう。
—
1. なぜViteは「CommonJS」に厳しいのか?
そもそも、なぜこのエラーが起きるのでしょうか。
Webpackはビルド時に全てのファイルをバンドルし、擬似的に `require` や `module.exports` をエミュレートする「魔法」をかけていました。しかし、Viteは違います。Viteはブラウザが直接解釈できる「ESM」をベースに開発サーバーを動かします。
レガシーなライブラリが `module.exports = …` と書いていると、ブラウザ上のVite開発サーバーは「これは何だ? `module` なんて定義されていないぞ!」と混乱するのです。これがエラーの本質です。
—
2. 禁断の解決策:`optimizeDeps` を使いこなす
Viteには、こうした「ESM非対応のライブラリ」を救済するための強力なゲートキーパーが存在します。それが `vite.config.ts` の `optimizeDeps` オプションです。
最も効果的な設定戦略
Viteに対し、「このライブラリはCommonJSで書かれているから、ブラウザで動くように事前に変換(プリバンドル)しておいてくれ」と指示を出します。
// vite.config.ts
import { defineConfig } from ‘vite’;
export default defineConfig({
optimizeDeps: {
// ESM非対応のライブラリをここに列挙する
// これにより、Viteは該当ライブラリを事前にESMに変換してから提供する
include: [‘legacy-library-name’, ‘another-old-lib’],
},
build: {
commonjsOptions: {
// 複雑なライブラリの場合、これが必要になることがある
// 変換対象を広げる設定だが、ビルド時間がわずかに増えるため注意
transformMixedEsModules: true,
}
}
});
なぜこれが必要か?
`optimizeDeps` を使うと、Viteは `node_modules` 内の該当ライブラリを一度 `esbuild` で読み取り、ESMに書き換えて `.vite` キャッシュディレクトリに保存します。これでブラウザは、レガシーなライブラリを「モダンなESMモジュール」として安全に読み込めるようになるのです。
—
3. それでも動かない場合の「切り札」
ライブラリが極端に古かったり、動的な `require` を多用している場合は、上記の設定でも力不足なことがあります。そんな時は、`vite-plugin-commonjs` を検討しましょう。
導入と設定のステップ
1. プラグインのインストール
npm install vite-plugin-commonjs –save-dev
2. 設定ファイルへの適用
import { viteCommonjs } from ‘@originjs/vite-plugin-commonjs’;
export default defineConfig({
plugins: [
// 全てのCommonJSモジュールをESMにトランスパイルする最終兵器
viteCommonjs()
]
});
注意点:
このプラグインは非常に強力ですが、ビルドプロセスにオーバーヘッドをかけます。まずは `optimizeDeps` で解決を試み、どうしてもダメな場合のみこのプラグインに頼るのが「アーキテクトの流儀」です。
—
4. 動作確認:成功のサインを見逃さない
設定を変更したら、必ず以下の手順で「キャッシュのクリーンアップ」を伴う再起動を行ってください。Viteのキャッシュが古いビルド情報を保持していると、設定を変えてもエラーが消えないからです。
キャッシュを強制削除して再起動
rm -rf node_modules/.vite && npm run dev
成功の確認ポイント:
ブラウザの開発者ツール(Networkタブ)を開き、該当のライブラリが読み込まれている箇所を見てください。
- 以前は `Uncaught ReferenceError` で止まっていた箇所が通過しているか。
- `Request URL` が `node_modules/.vite/deps/` 経由のものになっているか。
これを確認できれば、あなたは「レガシーの呪縛」から解き放たれ、モダンなViteの恩恵をフルに受け取れる準備が整ったということです。
—
最後に:ツールに振り回されるな
WebpackからViteへの移行は、単なるツールの入れ替えではありません。それは「古いモジュールシステムから、現代の標準的なESMへの適応」という、エンジニアとしての基礎体力を問うプロセスです。
最初はエラーと向き合うのが苦痛に感じるかもしれません。しかし、`optimizeDeps` の挙動を理解し、なぜモジュールが読み込めないのかという本質を掴んでしまえば、どんなライブラリが来ても怖くありません。
この知識を武器に、ぜひ明日からの開発を劇的に速く、そして快適なものにしてください。応援しています!