この記事でやりたいこと
以下の技術を使用して、 Laravel + React でWebアプリを構築していきます。
- Laravel Sail によるDocker開発環境の構築
- Laravel Breezeスターターキット(Inertiaを使用してフロントエンドにReactを実装)
- Laravel Breeze の認証機能
- TailwindCssを使った装飾
- 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
では、Laravel + React でWebアプリを構築する方法について、順を追って解説します。
1. Laravel Sail によるDocker開発環境の構築
Laravel Sail は、LaravelでDockerコンテナによる開発環境を提供してくれるコマンドラインインターフェースで、ローカルマシン内のソフトウェアや構成に干渉しない小型で軽量の「コンテナ」内でアプリケーションの開発を行うことができて便利です。
まずは、Laravelプロジェクトを新規作成します(Docker Desktopをインストールしていない場合は、インストールしてから実行して下さい)。
% curl -s "https://laravel.build/example-app" | bash
上記コマンドを実行すると、カレントディレクトリに新しくLaravelアプリケーションのディレクトリが作成されます。なお、コマンドのexample-app
の部分は自分の好きなアプリケーション名に変更できるので、変更してから実行することをおすすめします。
その後、作成したLaravelアプリケーションのディレクトリに移動して、Laravel Sailを立ち上げます。
% cd example-app
% ./vendor/bin/sail up
ローカルのブラウザからhttp://localhost
にアクセスして、Laravelアプリケーションが開ければOKです。
これでDockerコンテナ環境で開発を始められるようになりました。しかし、円滑に開発を進めるために、事前にタイムゾーンの変更とMySQLの文字コードの変更をしておく必要があります。具体的な手順については別記事にしたのでそちらをご覧下さい。↓
2. Laravel Breezeスターターキット(Inertiaを使用してフロントエンドにReactを実装)
今回はフロントエンドに React を使います。その場合、Inertiaというツールを使うと、フロント側(React)とバックエンド側(Laravel)の連携を自動で行ってくれます。Inertiaを導入する場合は色々と設定しなければいけないことがあるのですが、Laravel Breezeのスターターキットを使うと、それら諸々の設定も自動で行ってくれるのでさらに便利です。
ということで、Breezeを導入していきます。
下記のコマンドを実行して、Breezeをインストールします。
% ./vendor/bin/sail composer require laravel/breeze --dev
Breezeをインストールしたら、次はBreezeの動作に必要なファイル群を生成します。今回はフロントに React を使うので、最後にreact
と付け加えています(react以外にもvue
も指定できます)。
% sail artisan breeze:install react
上記コマンドを実行することで、フロントをReactで開発するのに必要なパッケージ群(reactやinertia等)の依存関係が追加されます。
少し composer.json と package.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"
},
}
{
"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)側の開発に必要な依存パッケージが記述されています(たぶん)。
では、ここで一度ブラウザでアプリを開いてみましょう。まずは下記のコマンドを実行します。
% 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ファイルをレンダーするというルーティングになっています。
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
に読み込まれて1つのページになります)。
また、 jsx のエントリポイントであるresources/js/app.jsx
では、cssのエントリポイントであるresources/css/app.css
ファイルが import されているので、app.cssのスタイルが全ての jsx ファイルに適用されます。
import './bootstrap';
import '../css/app.css'; // ← app.cssのimport!!!!
// 以下略...
3. Laravel Breeze の認証機能
次は Breezeの認証機能を追加していきます。
...とは言うものの、実は前のステップでBreezeのスターターキットを導入した際に一緒に導入されていました!
ブラウザでhttp://localhost/
にアクセスして画面右上をみてみると、ログイン機能が利用できるようになっていることが分かります。
4. TailwindCssを使った装飾
次に cssフレームワークである TailwindCss を導入していきます。この TailwindCss についても、Breeze を導入しているのであれば既にインストールされています。
TailwindCss の設定
既にこのまま TailwindCss を使うことができる状態ですが、本記事では TailwindCss の設定について少し詳しく見ていきます。
TailwindCss の設定は、プロジェクトルートの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ディレクティブが記述されています。
@tailwind base;
@tailwind components;
@tailwind utilities;
なお、このapp.css
ファイルは、jsx のエントリポイントであるresources/js/app.jsx
で import する必要があります(※本記事の手順通り進めてきた場合、既に import が記述されています)。
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です。
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ディレクティブを追加します。
<!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の実行
# Viteを開発環境で実行する
% npm run dev
# 本番環境用にアセットをバンドルし、バージョン付けする
% npm run build
以上で、Laravel + React でWebアプリの構築ができました!
参考