Laravel+React でWebアプリを構築する [使用技術: Laravel Sail, Laravel Breeze, Inertia, TailwindCss, Vite]

# この記事でやりたいこと
以下の技術を使用して、 Laravel + React でWebアプリを構築していきます。
1. Laravel Sail によるDocker開発環境の構築
1. Laravel Breezeスターターキット（Inertiaを使用してフロントエンドにReactを実装）
1. Laravel Breeze の認証機能
1. TailwindCssを使った装飾
1. Laravel Vite によるフロントエンドのビルド

(手順が多く複雑なので、自分用にメモを残すついでに記事にします...!）


## 動作環境
 - macOS    13.5.2
 - PHP    8.2.11
 - Laravel Framework    10.28.0
 - react    18.2.0
 - react-dom    18.2.0
 - Composer    2.6.5
 - node    v18.18.1
 - npm    10.2.0
 - laravel/sail    v1.25.0
 - Docker    23.0.5
 - laravel/breeze    v1.25.0
 - inertiajs/inertia-laravel    v0.6.10
 - @inertiajs/react    1.0.12
 - vite    4.4.11
 - tailwindcss    3.3.3
 - MySQL    8.0.32 
___
<br>
では、Laravel + React でWebアプリを構築する方法について、順を追って解説します。
<br>


## 1.　Laravel Sail によるDocker開発環境の構築

Laravel Sail は、LaravelでDockerコンテナによる開発環境を提供してくれるコマンドラインインターフェースで、ローカルマシン内のソフトウェアや構成に干渉しない小型で軽量の「コンテナ」内でアプリケーションの開発を行うことができて便利です。
まずは、Laravelプロジェクトを新規作成します（Docker Desktopをインストールしていない場合は、インストールしてから実行して下さい）。
~~~.terminal
% curl -s "https://laravel.build/example-app" | bash
~~~
上記コマンドを実行すると、カレントディレクトリに新しくLaravelアプリケーションのディレクトリが作成されます。なお、コマンドの`example-app`の部分は自分の好きなアプリケーション名に変更できるので、変更してから実行することをおすすめします。

その後、作成したLaravelアプリケーションのディレクトリに移動して、Laravel Sailを立ち上げます。
~~~.terminal
% cd example-app

% ./vendor/bin/sail up
~~~

ローカルのブラウザから`http://localhost`にアクセスして、Laravelアプリケーションが開ければOKです。
これでDockerコンテナ環境で開発を始められるようになりました。しかし、円滑に開発を進めるために、事前に**タイムゾーンの変更**と**MySQLの文字コードの変更**をしておく必要があります。具体的な手順については別記事にしたのでそちらをご覧下さい。↓

https://qiita.com/Sho-taro/items/feaaf025df15ab206994

## 2.　Laravel Breezeスターターキット（Inertiaを使用してフロントエンドにReactを実装）
今回はフロントエンドに React を使います。その場合、Inertiaというツールを使うと、フロント側（React）とバックエンド側（Laravel）の連携を自動で行ってくれます。Inertiaを導入する場合は色々と設定しなければいけないことがあるのですが、Laravel Breezeのスターターキットを使うと、それら諸々の設定も自動で行ってくれるのでさらに便利です。
ということで、Breezeを導入していきます。
下記のコマンドを実行して、Breezeをインストールします。
~~~.terminal
% ./vendor/bin/sail composer require laravel/breeze --dev
~~~

Breezeをインストールしたら、次はBreezeの動作に必要なファイル群を生成します。今回はフロントに React を使うので、最後に`react` と付け加えています（react以外にも`vue`も指定できます）。
~~~.terminal
% sail artisan breeze:install react
~~~
上記コマンドを実行することで、**フロントをReactで開発するのに必要なパッケージ群（reactやinertia等）の依存関係が追加されます**。
少し composer.json と package.json を覗いてみましょう（以下のコードは一部のみ抜粋）。

~~~composer.json
{
    "require": {
    "php": "^8.1",
    "guzzlehttp/guzzle": "^7.2",
    "inertiajs/inertia-laravel": "^0.6.3",
    "laravel/framework": "^10.10",
    "laravel/sanctum": "^3.2",
    "laravel/tinker": "^2.8",
    "tightenco/ziggy": "^1.0"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/breeze": "^1.25",
        "laravel/pint": "^1.0",
        "laravel/sail": "^1.18",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^7.0",
        "phpunit/phpunit": "^10.1",
        "spatie/laravel-ignition": "^2.0"
    },
}
~~~
~~~package.json
{
    "devDependencies": {
        "@headlessui/react": "^1.4.2",
        "@inertiajs/react": "^1.0.0",
        "@tailwindcss/forms": "^0.5.3",
        "@vitejs/plugin-react": "^4.0.3",
        "autoprefixer": "^10.4.12",
        "axios": "^1.1.2",
        "laravel-vite-plugin": "^0.8.0",
        "postcss": "^8.4.18",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "tailwindcss": "^3.2.1",
        "vite": "^4.0.0"
    }
}

~~~
多数の依存パッケージが追加されていることが分かります。ちなみに、composer.json は バックエンド（PHP / Laravel）側、 package.json はフロントエンド（React）側の開発に必要な依存パッケージが記述されています（たぶん）。

では、ここで一度ブラウザでアプリを開いてみましょう。まずは下記のコマンドを実行します。

~~~.terminal
% npm install     # 依存パッケージのインストール
% npm run dev     # 開発サーバーの立ち上げ
~~~
コマンドを実行後、ローカルのブラウザから`http://localhost`にアクセスしてみると、きちんとページを開くことができると思います。見た目はあまり変わっていませんが、フロントはきちんとReact(jsx)で書かれています。

### 余談 :  Reactのエントリポイントやルーティングの確認
少し細かい話になるので、早く先に進みたい方は次のステップまで読み飛ばしてしまってかまいません。
Breezeを使ってフロントにReactを導入したことで、`resources/js`ディレクトリ以下にたくさんのディレクトリ/ファイルが自動で追加されました。ここでは、新しく追加されたそれらのファイルをもう少し詳しく見ていきましょう。
#### jsx のエントリポイント
jsx のエントリポイントは、`resources/js/app.jsx`というファイルです。この app.jsx ファイルに、指定したルーティングに対応した `resources/js/Pages`ディレクトリ以下の jsx ファイルがレンダーされます。
具体例として、`http://localhost/`というURLにアクセスした場合を考えてみましょう。`routes/web.php`をみると、`'/'`というURLにアクセスした場合、`Welcome`というjsxファイルをレンダーするというルーティングになっています。
~~~web.php
Route::get('/', function () {
    return Inertia::render('Welcome', [
        'canLogin' => Route::has('login'),
        'canRegister' => Route::has('register'),
        'laravelVersion' => Application::VERSION,
        'phpVersion' => PHP_VERSION,
    ]);
});
~~~
ですので、`http://localhost/`というURLにアクセスした場合、 `resources/js/Pages/Welcome.jsx`が`resources/js/app.jsx`にレンダーされることになります（正確には、この`app.jsx`ファイルがさらに`resources/views/app.blade.php`に読み込まれて１つのページになります）。
また、 jsx のエントリポイントである`resources/js/app.jsx`では、cssのエントリポイントである`resources/css/app.css`ファイルが import されているので、app.cssのスタイルが全ての jsx ファイルに適用されます。

~~~resources/js/app.jsx
import './bootstrap';
import '../css/app.css';     // ← app.cssのimport!!!!
// 以下略...
~~~
___

## 3. Laravel Breeze の認証機能
次は Breezeの認証機能を追加していきます。
...とは言うものの、実は前のステップでBreezeのスターターキットを導入した際に一緒に導入されていました！
ブラウザで`http://localhost/`にアクセスして画面右上をみてみると、ログイン機能が利用できるようになっていることが分かります。
![スクリーンショット 2023-10-12 19.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486417/abecb3ef-ef8f-72da-279d-2942054397c2.png)

## 4. TailwindCssを使った装飾
次に cssフレームワークである TailwindCss を導入していきます。この TailwindCss についても、Breeze を導入しているのであれば既にインストールされています。

### TailwindCss の設定
既にこのまま TailwindCss を使うことができる状態ですが、本記事では TailwindCss の設定について少し詳しく見ていきます。
TailwindCss の設定は、プロジェクトルートの`tailwind.config.js`というファイルに書かれています。
~~~tailwind.config.js
import defaultTheme from 'tailwindcss/defaultTheme';
import forms from '@tailwindcss/forms';

/** @type {import('tailwindcss').Config} */
export default {
	content: [
		'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
		'./storage/framework/views/*.php',
		'./resources/views/**/*.blade.php',
		'./resources/js/**/*.jsx',
	],

	theme: {
		extend: {
			fontFamily: {
				sans: ['Figtree', ...defaultTheme.fontFamily.sans],
			},
		},
	},

	plugins: [forms],
};
~~~
この中で特に大事なのが`content`の部分です。`content`では、**どのファイルに書かれたTailwindCssを読み込むか**を記述しています。すなわち、TailwindCssを使いたいファイルのファイル名が`content`部分に記述されている、ということです。
上記の例では、`./resources/views/**/*.blade.php`や`./resources/js/**/*.jsx`が記述されているので、**resources/viewsディレクトリ以下のbladeファイル**や**resources/jsディレクトリ以下のjsxファイル**で TailwindCss が使えるようになっています。

### TailwindCssのエントリポイント
TailwindCss のエントリポイントについても理解しておく必要があります。デフォルトでは、`resources/css/app.css`がエントリポイントとなっています。`app.css`には、@tailwindディレクティブが記述されています。

~~~resources/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
~~~
なお、この`app.css`ファイルは、jsx のエントリポイントである`resources/js/app.jsx`で import する必要があります（※本記事の手順通り進めてきた場合、既に import が記述されています）。

~~~resources/js/app.jsx
import './bootstrap';
import '../css/app.css';     // app.css を importしている
// 以下略...
~~~
## 5. Laravel Vite によるフロントエンドのビルド
Vite（ヴィート）は、非常に高速な開発環境を提供してくれる、コードを本番用に構築する最新のフロントエンドビルドツールです。Laravelでアプリケーションを構築する場合、通常、Viteを使用してアプリケーションのCSSとJavaScriptファイルを本番環境用のアセットへ構築することになります。

### Viteの設定
（※本記事と同様の手順で進めてきた場合、既に自動で、以下で解説する内容通りに設定されています。）
Viteの設定は、プロジェクトルートの`vite.config.js`で行います。`Plugins.laravel`の箇所では、jsx や css のエントリポイントを指定する必要があります。css のエントリポイントについては、前のステップで述べたように既に jsx 側で import してあるので、ここでは css のエントリポイントは記述しなくてOKです。

~~~vite.config.js
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',    // jsx のエントリポイントを記述
            refresh: true,
        }),
        react(),
    ],
});
~~~

### jsx と css の読み込み
Viteのエントリポイントを設定したら、アプリケーションのルートテンプレート（今回の場合は`resources/views/app.blade.php`）のheadタグ内に @vite Bladeディレクティブを追加します。

~~~resources/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <!-- 中略 -->
        <!-- ↓ ココ！！！！！ -->
        @vite(['resources/js/app.jsx', "resources/js/Pages/{$page['component']}.jsx"])
        @inertiaHead
    </head>
    <body class="font-sans antialiased">
        @inertia
    </body>
</html>
~~~

### Viteの実行
~~~.terminal
# Viteを開発環境で実行する
% npm run dev

# 本番環境用にアセットをバンドルし、バージョン付けする
% npm run build
~~~

___
以上で、Laravel + React でWebアプリの構築ができました！

## 参考
https://readouble.com/laravel/10.x/ja/installation.html

https://readouble.com/laravel/10.x/ja/starter-kits.html

https://readouble.com/laravel/10.x/ja/vite.html