この記事ではLaravelにInertia.jsをインストールしてHello Worldを出力する方法までを解説します。

前の記事でInertiaが何なのかということについては大体わかったのですが、じゃあいったいどうやって使うんでしょうか?

では今回はLaravelにInertia.jsを導入して簡単なサンプルを作成してみましょう!
前回の記事でInertia.jsについて、どういうものか概要を解説しています。そちらも合わせてお読みください。
- Laravel 8 (執筆時のバージョンは8.77.1)
- jetstream with inertia
npm list --depth=0
+-- @inertiajs/inertia@0.10.1
+-- @inertiajs/inertia-vue3@0.5.2
+-- @inertiajs/progress@0.2.6
+-- vue@3.2.26
`-- vue-loader@16.8.3
composer show -i
inertiajs/inertia-laravel v0.4.5 The Laravel adapter for Inertia.js.
laravel/framework v8.77.1 The Laravel Framework.
laravel/jetstream v2.5.0 Tailwind scaffolding for the Laravel framework.
Laravelのインストール
この記事では、Laravel8を用いて解説を進めていきます。Laravelの環境構築についてはこちらの記事も参考にするとDockerを使用して楽にLaravelの開発環境を構築できます。
以降のコマンドはLaravelをインストールしたディレクトリで実行します。上記のDockerでLaravel環境を構築している場合は、「make app」または「docker-compose exec app bash」を実行してLaravelのコンテナに入ってから実行して下さい。
サーバーサイドの設定
Inertia.jsはサーバーサイドとクライアントサイド両方に関わってきます。まずはサーバーサイドの設定をしていきます。
jetstreamのインストール
composerで「laravel/jetstream」をインストールします。jetstreamはLaravel8から採用された認証系のプラグインです。ユーザー登録、ログイン、二要素認証、パスワードリセットなどの機能を備えています。
composer require laravel/jetstream
jetstreamではスタックとしてLimewireを使用するかInertia.jsを使用するか選択できます。今回はInertia.jsを使用する方法でセットアップしていきます。
#チーム機能を使わない場合
php artisan jetstream:install inertia
#チーム機能を使う場合
php artisan jetstream:install inertia --teams
jetstreamのデータベースのマイグレーションを行います。
php artisan migrate
次に、上述のDockerでの環境を構築している場合は、appコンテナから出て、webコンテナに入りnpmパッケージのインストール作業とコンパイルをします。
exit
make web
npm install && npm run dev
ルートテンプレートを確認
ここまで行うと、最初のアクセス時に読み込まれるルートテンプレートファイルが自動的に作成されています。これはフルHTMLで、必要なJSやCSSを読み込みなどもこのテンプレートで行われます。
<body>タグに囲まれている「@inertia」ディレクティブが、このAppの大元となります。
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title inertia>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
<!-- Styles -->
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
<!-- Scripts -->
@routes
<script src="{{ mix('js/app.js') }}" defer></script>
</head>
<body class="font-sans antialiased">
@inertia
@env ('local')
<script src="http://localhost:3000/browser-sync/browser-sync-client.js"></script>
@endenv
</body>
</html>
ルーティングとレスポンスを作成
まずは、ルーティングを管理している「routes/web.php」を編集し、コントローラーを作成せずに直接ビューを返すルーティングを追加してみましょう。
「/HelloWorld」にアクセスがあった時、「HelloWorld」ビューを返すInertiaレスポンスは次のように書きます。これを「routes/web.php」の末尾に追記します。
Route::get('/HelloWorld', function () {
return Inertia::render('HelloWorld');
});
フロントエンド側の設定
今度はクライアントサイドの設定です。Vue.jsのコンポーネントを作成していきます。
Vue.jsのPageコンポーネントを作成
「resources/js/」配下に「Pages」というディレクトリができているかと思います。ここにVue.jsのコンポーネントファイルを配置していきます。
「HelloWorld.vue」というファイル名でHello Worldと表示するだけのコンポーネントファイルを作成します。
<template>
<div>
Hello world!
</div>
</template>
保存したらWebコンテナで下記を実行します。これでアセットファイルの更新を検知して自動的にコンパイルしてくれます。
npm run watch
browsersyncでホットリロード(オプション)
もしホットリロード(ソースを更新した際にブラウザを自動で再読み込みする機能)を有効にしたい場合は「webpack.mix.js」を編集して.browserSync()の設定を加えると、ホットリロード用のポートでbrowserSyncが立ち上がり、そのポート経由でホットリロードが行えるようになります。
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
])
.webpackConfig(require('./webpack.config'))
.browserSync({
files: [
'./resources/**/*',
'./app/**/*',
'./config/**/*',
'./routes/**/*',
'./public/**/*'
],
proxy: {
target: "http://localhost/",
}
});
if (mix.inProduction()) {
mix.version();
}
「http://localhost/HelloWorld」または、「http://localhost:3000/HelloWorld」にアクセスして「HelloWorld」と表示されていれば成功です。
Inertia-linkの動作確認
Inertia.jsでは、<inertia-link>というコンポーネントを使用してリンクを作成すると、クリックした際にXHRでのリクエストがされるようになります。この動作を確認してみます。
「HelloWorld.vue」にホームへ戻る<inertia-link>を追加します。
<template>
<div>
Hello world!
<inertia-link href="/" class="text-sm text-blue-700 underline">
ホームへ戻る
</inertia-link>
</div>
</template>
<script>
import { InertiaLink } from '@inertiajs/inertia-vue3'
export default {
components: {
InertiaLink,
}
}
</script>
「http://localhost/HelloWorld」にアクセスすると「HelloWorld ホームへ戻る」と表示されます。
ブラウザの開発者ツールでネットワークを見てみると、HTMLが返ってきていることが分かります。このように初回のアクセスはフルHTMLが返ります。
インスペクタでDOMツリーをみると、リンクは普通にaタグで作成されていることが分かります。ただし、クリックイベントを補足するイベントリスナーが登録されており、クリック時に通常のリクエストを送るのではなく、XHRリクエストを送信するメソッドが呼び出されているということが推察できます。
<a class="text-sm text-blue-700 underline" href="http://localhost/"> ホームへ戻る </a>
次に「ホームへ戻る」のリンクをクリックするときのリクエストを見てみます。
X-Inertia: true
X-Inertia-Version: 207fd484b7c2ceeff7800b8c8a11b3b6
「X-Inertia」ヘッダーが付加されて送信されていることが分かります。レスポンスを見てみると
Content-Type: application/json
JSONオブジェクトが返ってきていることが分かります。それでも画面上は初回のアクセスしたトップページと同じものが表示されています。このようにInertia.jsが、クライアントサイドではリンクをXHRに変えてリクエストを送り、サーバーサイドではX-Inertiaヘッダーの有無をチェックしてフルHTMLを返すかJSONデータのみを返すかを決定していることが分かります。
ソースコード
今回のソースコードはGitHubで公開しています。
Comments