Viteを使用したLaravelプロジェクトの本番環境設定

# はじめに
Laravel 9以降では、Viteがデフォルトのビルドツールとして採用されています。

今回はLaravelでViteを使用し、Reactでフロントエンドを作成する。といった設計で、実際にどのように設定するのかを書いていこうと思います。
### Viteとは？
公式ドキュメントには以下のように説明されています。
> Vite（フランス語で「素早い」という意味の単語）は、現代の Web プロジェクトのために、より速く無駄のない開発体験を提供することを目的としたビルドツールです。


ビルドツールとは、ソフトウェア開発においてソースコードを最終的な実行可能な形式に変換するために使用されるツールのことです。

コンパイル、リンキング、パッケージング、テスト、デプロイメントなどのビルドプロセスを自動化し、効率化するために利用されます。

Viteは、特に**開発速度とシンプルさに重点を置いたビルドツール**であり、以下のような特徴を持っています。

- 高速な開発サーバー起動とHMR
- ネイティブのESモジュールサポート
- シンプルな設定ファイル
- 効率的なビルドプロセス
- 豊富なプラグインエコシステム

これらの特徴により、Viteはモダンなフロントエンド開発において非常に強力なツールとなっています。

### なぜLaravelにViteを使用するのか
LaravelでViteを使用する理由は、フロントエンド開発をより効率的に行うためです。

LaravelとViteは、それぞれバックエンドとフロントエンドの開発を効率化するためのツールです。

**Viteは特にフロントエンド開発の速度と効率性を向上させるために設計されており**、Laravelの柔軟なテンプレートシステムと統合できます。

# LaravelとViteの統合例
では実際にどうやって統合するかを見ていきましょう。

- **1 Laravelでプロジェクトの作成**
まず、Laravelプロジェクトを作成し、必要なセットアップを行います。

- **2 Viteのインストール**
次に、Viteと必要なプラグインをインストールします。

- **3 Viteの設定**
Laravelのルートディレクトリにvite.config.jsファイルを作成し、以下の内容を追加します。
```javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.jsx',
            refresh: true,
        }),
        react(),
    ],
    build: {
        manifest: true,
        outDir: 'public/build',
    	assetsDir:'.',
        rollupOptions: {
            input: 'resources/js/app.jsx',
    	    output:{
        		entryFileNames: 'assets/[name]-[hash].js',
                chunkFileNames: 'assets/[name]-[hash].js',
                assetFileNames: 'assets/[name]-[hash][extname]',
            },
        },
    },
});
```
この設定ファイルでは、LaravelプロジェクトでReactを使用するための設定に加え、Viteがビルドするエントリーポイントの指定、本番用のビルド設定も行っています。


- **4 Reactコンポーネントの作成**
先ほど指定したエントリーポイントであるresources/js/app.jsxファイルを作成し、以下の内容を追加します。

```jsx
import ReactDOM from "react-dom/client";
import { Journaling } from "./components/Journaling";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(
    <Router>
        <Routes>
            <Route path="/" element={<Journaling />} />
        </Routes>
    </Router>
);
```
上記のJournalingは自作のReactコンポーネントです。
"/"（ルートパス）がリクエストされると、<Journaling />コンポーネントが表示されます。

トップページとして表示したいコンポーネントを配置してください。

- **5 Bladeテンプレートの設定**
resources/views/welcome.blade.phpファイルを編集し、以下のように変更します。
```blade
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>MoodTune</title>

	@if (app()->environment('local'))
        <!-- 開発環境用 -->

        @viteReactRefresh
        @vite(['resources/css/app.module.css', 'resources/js/app.jsx'])

	@else
        <!-- 本番環境用 -->
        @php
	$manifestPath = public_path('build/.vite/manifest.json');
            if (file_exists($manifestPath)) {
                $manifest = json_decode(file_get_contents($manifestPath), true);
            } else {
                throw new Exception('The Vite manifest file does not exist.');
            }
        
        $jsFile = $manifest['resources/js/app.jsx']['file'] ?? null;
        $cssFiles = $manifest['resources/js/app.jsx']['css'] ?? [];
        @endphp
        @foreach ($cssFiles as $cssFile)
            <link rel="stylesheet" href="{{ secure_asset('build/' . $cssFile) }}">
        @endforeach
        @if ($jsFile)
            <script src="{{ secure_asset('build/' . $jsFile) }}" defer></script>
        @endif
    @endif

        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,600&display=swap" rel="stylesheet" />
        
       
    </head>
    <body class="font-sans antialiased dark:bg-black dark:text-white/50">
    <div id="app"></div>
    </body>
</html>

```
上記のコードはコメントアウトされている通り、開発環境と本番環境をapp()->environment('local')で振り分け、それぞれに適したコードを実行します。

本番環境ではビルドで生成されたマニフェストファイルを参照し、そのマニフェストからビルドファイルのパスを取得します。
取得したファイルパスを使用して、適切なリンクタグやスクリプトタグをHTMLに挿入します。

- **6 開発サーバーの起動**
以下のコマンドで開発サーバーを起動します。
```bash
npm run dev
php artisan serve
```

これで、LaravelとViteを使用してReactでフロントエンドを作成する設定が完了しました。

# まとめ
LaravelとViteの設定についてお話させて頂きました。

記事で設定の内容をまとめましたが、実際に行うと様々なエラーがあると思います。
しかし一度設定を行うとViteを使用することでLaravelでも簡単にSPAの構成を実装できます。

最初は設定やエラー対応に時間がかかるかもしれませんが、興味のある方はぜひ使用してみてはどうでしょうか。

私も引き続き、この構成で開発に専念しようと思います！