本記事で作成するプロジェクトはGithubのリポジトリに置いてあります。是非ご覧ください。
また、ReactではなくVueと接続したいという方は、こちらのQiitaの記事をご覧ください。
フロントエンドとバックエンドを接続するInertia.js
バックエンドフレームワークのLaravelとフロントエンドフレームワークのReactは、どちらも素晴らしいフレームワークだと思います。双方のメリットを活かしてウェブアプリケーションを作成したいと考えるのは当然でしょう。それを実現してくれるのがInertia.jsです。Inertiaを使用すると、それぞれ切り分けて開発されたLaravelとReactを接続することができます。非常に便利ですね。
ただ、バージョン9への移行に伴い、Laraevlはそれまで利用していたwebmixからviteを使用するようになり、既存の解説記事の手順ではInertiaを導入できなくなってしまいました。また、Inertiaのドキュメントが不足していることもあり、導入がそもそも自力で導入するのが難しいです。そこで、自分の備忘録という意味も含め、LaravelとReactを導入する方法をこの記事で説明します。
以下では、Laravel9, npm, composerはインストール済みであると仮定します。Laravel及びReactの知識があると理解しやすいかとは思いますが、なくても大丈夫です。
各種インストール
以下のコマンドでプロジェクトの作成を行います。プロジェクト名は"laravel9-react-inertiajs"としました。
composer create-project laravel/laravel laravel9-react-inertiajs
プロジェクトディレクトリに移動します。
cd laravel9-react-inertiajs
次に、各種必要なReact関連のパッケージをインストールします。
npm install --save-dev react-dom react
npm install --save-dev @vitejs/plugin-react
npm install --save-dev @inertiajs/inertia-react
viteは、ここではReactを高速にコンパイルするライブラリと捉えて差し支えありません。以前のLaravelでは使用されていたwebmixはviteに置き換わりました。Laravel9を使用していれば、vite.config.js
というファイルがあり、以下のように記載されていると思います。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.jsx'],
refresh: true,
}),
],
});
laravel.inputには、Laravelからvueに渡されるファイルを定義します。エントリポイントのファイルだけでよく、app.jsxがimportしているファイル全てをここに記載する必要はありません。SPAを作成していて、CSSをVue側で読み込む場合には、'resources/css/app.css'は削除して問題ありません。
app.js以外のファイルを使用する場合には、適宜名前を変更します。
ここで一つ注意が必要なのは、拡張子をapp.jsではなく、app.jsxにしなくてはならない点です。viteがうまく処理してくれなくなります。基本的に、viteを使う場合はjsx拡張子を使うのが良さそうです。
このvite.config.jsに、プラグインとして、vueを渡してあげます。vite.config.jsは以下のようになります。これによって、viteがうまくvueのコンパイルを行ってくれます。
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
laravel({
input: ["resources/css/app.css", "resources/js/app.jsx"],
refresh: true,
}),
react(),
],
});
Inertiaの設定
まず、Inertiaをインストールしましょう。
composer require inertiajs/inertia-laravel
次に、Inertiaのミドルウェアを作成します。
php artisan inertia:middleware
これでミドルウェアが作成されました。
次に、app/Http/Kernel.phpに以下を追記します。
'web' => [
// ...
\App\Http\Middleware\HandleInertiaRequests::class,
],
CreateInertiaAppの作成
次に、resources/js/app.jsx
を編集します。vite.config.jsでは、このファイルをエントリポイントとしてコンパイルを行うようにしました。app.jsxの役割は、一言で言えばルーティングです。Laravelから渡されたrouteを基に、どのページを表示するかを決定します。app.jsxは以下のように記述します。(ここの情報、あまりまだネットに出回ってないですね...)
import React from "react";
import { render } from "react-dom";
import { createInertiaApp } from "@inertiajs/inertia-react";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
createInertiaApp({
resolve: (name) =>
resolvePageComponent(
`./Pages/${name}.jsx`,
import.meta.glob("./Pages/**/*.jsx")
),
setup({ el, App, props }) {
render(<App {...props} />, el);
},
});
createInertiaAppという関数に渡されたresolveに注目すると、name
へのルーティングが./Pages/$(name).jsx
へのルーティングとして処理されることがわかると思います。ここのフォルダは変えてしまっても問題ありませんが、拡張子は.jsx
にしておかないとコンパイルエラーが出るようです。
app.blade.phpとReactの連携
次に、resources/views/app.blade.php
を作成します。これは、Reactでのindex.htmlを編集するようなものだと考えておけば大丈夫です。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
@inertiaHead
@viteReactRefresh
@vite(['resources/css/app.css', 'resources/js/app.jsx'])
</head>
<body>
@inertia
</body>
</html>
適宜、vite内の'resources/js/app.css'は削除してください。
1つ注意が必要なのは、Reactを用いる場合には、@viteReactRefresh
ディレクティブが必要な点です。これは、Vueを使用する際には必要ありません。
Routing
ルーティングの設定を行います。routes/web.php
を開いてください。初期の状態では、以下のようになっていると思います。
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
このRoutingの部分でも、Inertiaとの接続が必要です。以下のように変更します。ここでは、インデックスページに来たリクエストに対して、hello-world.vue
を表示するように設定します。ここは適宜変更してください。アプリケーションが大規模になる場合には、もちろんコントローラーにコードを移してください。
<?php
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return Inertia::render('hello-world');
});
Reactファイルの作成
いよいよReactファイルを作成してみます。resources/js/Pages/hello-world.jsx
を作成します。ここではReactファイルが正しく表示されるかどうかだけを確認したいので、単純な以下のファイルを作成します。
export default function HelloWorld() {
return (
<div>
<p>Hello World!</p>
</div>
);
}
動作確認
以上で準備は終了です。最後にターミナルを2つ開いて、以下のコマンドをそれぞれ実行して、正しく動作しているか確認してみましょう。
php artisan serve
npm install && npm run dev
Hello World!と表示されていれば成功です。
デプロイ
デプロイする際には、以下のコマンドを実行すれば、publicフォルダ内にコンパイルされたcss, jsファイルが生成されます。あとは、通常のLaravelと同様にデプロイしてあげてください。