Laravel MixとViteの違いを理解する:フロントビルド移行の判断材料
概要
Laravel 9.19 以降、新規プロジェクトのフロントエンドビルドツールのデフォルトが Laravel Mix から Vite に切り替わりました。既存の Mix ベースのプロジェクトはそのまま動き続けるため、「移行すべきか・そのままにするか」という判断を迫られる場面が少なくありません。
この記事では、Laravel Mix と Vite の設計思想の違いを整理し、移行判断のための材料を公開情報ベースでまとめます。特定の案件の構成ではなく、一般的な Laravel プロジェクトを前提とします。
両者の立ち位置
Laravel Mix と Vite は、同じ役割を別の思想で解いているツールです。
- Laravel Mix: webpack を薄くラップし、
mix.js()/mix.sass()のようなチェーン API で書けるようにしたもの。実体は webpack なので、最終的に全モジュールをバンドルします。 - Vite: 開発時はブラウザのネイティブ ES Modules を活用し、リクエストされたモジュールだけをオンデマンドで変換します。本番ビルドは Rollup を使用します。
端的に言えば、Mix は「設定を隠した webpack」、Vite は「開発体験を根本から作り直したツール」です。
設計思想の違い
開発サーバーの仕組み
最大の違いは開発時のアプローチにあります。
- Mix(webpack): 変更のたびに依存グラフを辿ってバンドルを再生成します。プロジェクトが大きくなるほど、起動とリビルドが遅くなりがちです。
- Vite: 全体をバンドルせず、必要なモジュールだけを都度変換します。そのため規模が大きくても開発サーバーの起動が速く、HMR も変更ファイル単位で効きます。
本番ビルド
Mix は webpack、Vite は Rollup がバンドルとコード分割を担当します。
設定ファイル
Mix は webpack.mix.js、Vite は vite.config.js を使い、記述スタイルが大きく異なります。
移行で詰まりやすいポイント
Mix から Vite への移行では、以下が典型的な詰まりどころです。
- アセット参照の書き方(
mix()ヘルパ →@viteディレクティブ) - 画像・フォントの相対パス解決の違い
- jQuery プラグインなどグローバル前提の古いライブラリ
- 環境変数(
process.env.MIX_XXX→import.meta.env.VITE_XXX) - Blade 内に
<script src="/js/app.js">でハードコードした箇所
これらは「webpack が全部バンドルして静的な成果物を吐く」前提のコードが、ESM をベースに解決する Vite の思想とズレることに起因します。
具体的な移行手順
Blade 側のアセット参照
{{-- Mix --}}
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
<script src="{{ mix('js/app.js') }}"></script>
{{-- Vite --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
設定ファイルの移行
// webpack.mix.js (Mix)
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.version();
// vite.config.js (Vite)
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
});
version() に相当するキャッシュバスティングは、Vite が自動でハッシュ付きファイル名を生成するため、個別の指定は不要になります。
環境変数
// Mix const apiBase = process.env.MIX_API_BASE; // Vite const apiBase = import.meta.env.VITE_API_BASE;
.env 側のプレフィックスも MIX_ から VITE_ へ変更します。
グローバル前提のライブラリ
jQuery 依存の古いプラグインを使っている場合は、resources/js/bootstrap.js などで明示的にグローバルへ割り当てるか、ESM 対応版へ差し替えます。剥がせない依存が多いほど、移行の難易度は一段上がります。
確認方法
npm run devで開発サーバーが起動し、HMR が効くかnpm run build後にpublic/build/manifest.jsonが生成されるか- レンダリング済みページで CSS / JS が 404 にならずロードされるか(ブラウザの Network タブで確認)
- 本番相当環境でハッシュ付きファイル名が正しく参照されているか
判断材料のまとめ
| 観点 | Laravel Mix | Vite |
|---|---|---|
| 実体 | webpack ラッパー | 開発=ESM / 本番=Rollup |
| 開発サーバー | 全体バンドル(規模で遅くなりがち) | オンデマンド変換(規模に強い) |
| 設定ファイル | webpack.mix.js |
vite.config.js |
| キャッシュバスティング | .version() |
自動 |
| 環境変数 | MIX_ / process.env |
VITE_ / import.meta.env |
| 公式の立ち位置 | メンテナンスモード | 新規プロジェクトのデフォルト |
まとめ
Laravel Mix と Vite の移行判断は、「開発体験の改善がどれだけ効くか」と「グローバル前提ライブラリの棚卸しコスト」の2点に集約されます。
- 新規・中規模以上・長期運用なら Vite を前提に
- 完成間近・短期・依存が薄いなら Mix のままでも問題なし
Mix はメンテナンスモードに入っているため、長期運用のプロジェクトでは「いつか移行する前提」をチームで共有しておくと、将来の意思決定が楽になります。「移行しない」という選択も含めて、理由を言葉にして選べることが最も重要です。
