Laravel+Inertia.jsのインストールとHello World Inertia入門#2

Laravel

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

Laraveler
Laraveler

前の記事で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>を追加します。

inertia-vue3のバージョン0.5.0以降では<inertia-link>コンポーネントが自動的に読み込まれなくなっているため、明示的にimportする必要があります。

<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データのみを返すかを決定していることが分かります。

今回の内容
  • jetstreamをインストールして、LaravelにInertia.jsの動作環境を作成
  • 簡単なVueコンポーネントを作成し、Inertia.jsでルーティング
  • Inertia-linkを使用して、XHRリクエストになるリンクを作成

ソースコード

今回のソースコードはGitHubで公開しています。

次回は、コントローラーからInertiaレスポンスを返す方法と、Inertiaでルーティングをする方法を取り上げます。

Inertia.js入門記事一覧
Inertia.jsでシンプルにSPAを構築する Inertia入門#1
Inertia.jsを使うとLaravelやRubyonRailsなどのフレームワーク上でAjax用のAPIやコントローラーを作成しなくても、通常のビューを使う要領でSPA(シングルページアプリケーション)が構築できます。
Laravel+Inertia.jsのインストールとHello World Inertia入門#2
この記事ではLaravelにInertia.jsをインストールしてHelloWorldを出力する方法までを解説します。
Inertia.jsのルーティングとレスポンス作成 Inertia入門#3
Laravel8でjetstreamを入れるとLimewireかInertiaかを選べます。この記事ではInertiaを使ってルーティングやInertiaレスポンスの返し方を解説します。
Inertia.jsでページレイアウト Inertia入門#4
この記事では、ページレイアウトについて解説します。親レイアウトに子ページを組み込むことで、ヘッダーやフッターを共通化できます。
Inertia linkの使い方 Inertia.js入門 #5
この記事では、Inertia linkについて解説します。
InertiaでXHRリクエスト Inertia.js入門 #6
この記事では、Inertia.jsで非同期通信を行うInertia.visit()について解説します。
Inertia.jsでのフォームとリダイレクト Inertia.js入門 #7
この記事では、Inertia.jsでのフォーム送信とリダイレクトについて解説します。
Inertiaでのバリデーション Inertia.js入門 #8
この記事では、Inertia.jsを使った際のバリデーションエラーの表示について解説します。
Inertiaで共通データとフラッシュメッセージ Inertia.js入門 #9
この記事では、Inertiaのレスポンスに毎回同じデータを含める方法やフラッシュメッセージの使い方について解説します。

Comments

タイトルとURLをコピーしました