Laravel8から認証パッケージにJetstreamが登場しInertia.js、 LivewireなどLaravelフレームワークの理解を深めるためにはこれらの新しい技術を理解する必要があります。

現行バーションのLaravelでInertia.jsを利用しようとした場合にはLaravel BreezeかLaravel Jetstreamを利用することができます(それらのパッケージを利用しなくてもInertia.jsを個別にインストールして利用することも可能)。本文書を公開したのはLaravel8がリリースされた直後でLaravel Breezeが存在しなかったこともありLaravel Jetstreamを利用してInertia.jsの説明を行っています。

Laravelのバージョン8からInertia.jsを利用することでVue, React, Blade(+Alpine.js)で作成されたscaffolding(ログイン、ユーザ登録画面など)、Livewireを利用することでPHP + Bladeで作成されたscaffoldingでフロントエンドの開発を行うことができます。VueやReactなどJavaScriptによるフロントエンドの開発者はInertia.js、PHPでバックエンドのLaravelとフロントエンド部分を作成したい開発者はLivewireを利用することになるかと思います。Inertia.jsやLivewireを利用しなくてもBladeを利用した従来の方法でフロントエンド側の画面を作成することは可能です。

本文書はInertia.jsってどんな技術なのか頭の中が??だらけの人を対象にJetStreamパッケージをインストールした環境でのInertia.jsの使い方をシンプルなコードを利用して説明しています。本文書を読んだだけではInertia.jsを利用したアプリケーションを構築することはできませんがInertia.jsがどのようなものかの理解は深まると思います。

Vue.jsのpropsなどVue.jsの基本知識を持っている人を前提に説明しています。

Laravel9, Laravel8で動作確認を行っていますがLaravel9環境で実行した内容に更新しています。

Laravelのインストール

最初にLaravel9またはLaravel8のインストールを行います。Mac環境でのLaravel8のインストールは下記の文書で公開ずみなので参考にしてください。

Laravel JetstremaでInertia.jsを利用するためにlaravelコマンドでオプションの–jetを使いInertiaの選択を行うことができます。


 % laravel new laravel_jetstream --jet
laravel new –helpで確認すると–jetの他に–stackといったオプションもあり事前にLivewireかinertiaを利用するか指定ることも可能です。

livewireとinertiaの選択ができますが、ここではinertiaを選択します。


Which Jetstream stack do you prefer?
  [0] livewire
  [1] inertia
 > 1

teamsを利用するかどうか確認がありますが今回は利用しないのでNoを選択します。デフォルトでは”no”の選択になります。


 Will your application use teams? (yes/no) [no]:
 > no
Laravelインストール後にパッケージで追加することは可能です。

JetsteamのインストールではJavaScriptのライブラリのインストールとコンパイルを行うため作成されるプロジェクトフォルダに移動します。


% cd laravel_jetstream 

php artisan serveコマンドを実行して開発サーバのhttp://127.0.0.8000にアクセスするとデータベースが存在しないために下記のエラー画面が表示されます。

接続時のエラーメッセージ
接続時のエラーメッセージ

Laravelにアクセスするためにはデータベースが必要になるのでデータベースの準備をしてください。本文書ではSQLiteを利用してデータベースを作成しています。

touchコマンドでdatabaseフォルダの下にdatabaase.sqliteファイルを作成します。


% touch database/database.sqlite

.envファイルを開いて先頭にDB_がついた環境変数の中からDB_CONNECTIONのみを残して他を削除します。DB_CONNECTIIONにはデフォルトでmysqlが設定されているのでsqliteに変更します。


DB_CONNECTION=sqlite

データベースの設定完了後はphp artisan migrateコマンドを実行してください。


 % php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (3.97ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (2.40ms)
Migrating: 2014_10_12_200000_add_two_factor_columns_to_users_table
Migrated:  2014_10_12_200000_add_two_factor_columns_to_users_table (3.71ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (2.43ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (2.81ms)
Migrating: 2022_04_05_233003_create_sessions_table
Migrated:  2022_04_05_233003_create_sessions_table (3.14ms)

データベース作成後にphp artisan migrateを実行して以下の画面が表示されるか確認してください。左上にはLoginとRegisterのリンクが表示されます。

login、registerが表示されたトップ画面
login、registerが表示されたトップ画面

ユーザの登録

右上のRegisterのリンクからユーザの登録を行い、Dashboardの画面を表示してください。

ユーザ登録後のdashboard画面
ユーザ登録後のdashboard画面

このDashboardの画面がどのように表示されるかを確認するためweb.phpファイルを開きます。Inertia\Inertia::renderを確認することができます。


Route::get('/', function () {
    return Inertia::render('Welcome', [
        'canLogin' => Route::has('login'),
        'canRegister' => Route::has('register'),
        'laravelVersion' => Application::VERSION,
        'phpVersion' => PHP_VERSION,
    ]);
});

Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    Route::get('/dashboard', function () {
        return Inertia::render('Dashboard');
    })->name('dashboard');
});

Inertia::render関数で指定しているDashboardはresources¥viewsディレクトリの中ではなくresources¥js¥Pagesの下にあるDashboard.vueファイルです。bladeファイルではなくvueファイルなのもポイントです。

本当にこのファイルの内容が表示されているのか確認するためにDashboardの文字を変更してみてください。これまで利用していたPHPのbladeファイルではファイルを更新すると即座に変更が反映されていましましたがvueファイルを更新してリロードしても更新内容は反映されません。vueファイルであるため更新させるためにはJavaScriptのコンパイルが必要なのでnpm run watchコマンドを実行しておく必要があります。


 % npm run watch

実行後にDashboard.vueファイルを下記のように変更するとブラウザにも変更が反映されます。Dashboardという文字列にInertiaを追加しています。


<template>
    <app-layout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Dashboard Inertia
            </h2>

DashboardにInertiaが追加されたので間違いなくweb.phpファイルで指定されているDashboardがこのresources¥js¥PagesにあるDashboard.vueファイルであることがわかります。

表示される内容が変わる
表示される内容が変わる

ここまでの動作確認で拡張子vueを持つファイルを利用しているのでinertiaではVue.jsを利用していることは間違いないということがわかったかと思います。インストールされているVue.jsのバージョンを確認したい場合にはpackage.jsonファイルで確認することができます。vueのバージョンは3.2.31です。


//略
        "axios": "^0.25",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "postcss-import": "^14.0.2",
        "tailwindcss": "^3.0.0",
        "vue": "^3.2.31",
        "vue-loader": "^17.0.0"
    }

なぜこれまでのバージョンとは異なりVue.jsを利用するのにinertiaが入っているのでしょう?この疑問についてこれから確認していきます。

Userデータの作成

Inertiaの動作確認に利用するためにseeding機能を利用してusersテーブルにダミーデータを登録します。

ダミーデータを入れるためにdatabase¥seeders¥DatabaseSeeder.phpファイルを開いてコメントを外します。


namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        \App\Models\User::factory(10)->create();
    }
}

php artisan db:seedコマンドを実行します。


 % php artisan db:seed
Database seeding completed successfully.

データの準備は完了です。データが登録されているかはTablePlusなどのGUIのアプリケーションを利用するか直接データベースへの接続またはphp artisan tinkerを利用してください。


% php artisan tinker
Psy Shell v0.11.2 (PHP 8.0.7 — cli) by Justin Hileman
>>> User::all();
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#4562
     all: [
       App\Models\User {#4564
       //略

Inertia.jsを利用してユーザ一覧を表示

Userコントローラーを作成

php artisan make:controllerコマンドでUser用のコントローラーを作成します。


% php artisan make:controller UserController
Controller created successfully.

ルーティングを追加

web.phpファイルにルーティング/userを追加し、UserControllerを指定します。


Route::resource('/user','App\Http\Controllers\UserController');

User/Index.vueファイルを作成

ルーティングの追加が完了したのでUserController.phpファイルを更新します。Inertia::renderを使ってUser/Indexを指定します。これはDashboardの時に説明しましたがbladeファイルではなくvueファイルでresource/js/Pages以下のUser/Indexを指しています。そのファイルにUser:all()でusersテーブルのユーザ情報をusersという名前で渡しています。


namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;

class UserController extends Controller
{

    public function index()
    {

        return Inertia::render('User/Index',['users' => User::all()]);
        
    }

}

resource/js/Pagesの下にはUser/Index.vueファイルは存在しないので作成を行います。Inertiaのrender関数で渡していたusersはvueファイルにpropsとして渡すことができます。

これまでLaravelのvueファイル内でユーザ一覧を取得し使用とした場合は大まかに以下のような処理を行う必要がありました。

  1. api.phpファイルにルーティングを追加
  2. vueファイルのライフサイクルフック内でaxios, fetchのgetメソッドで追加したルーティングにアクセス
  3. 取得したデータをvueのデータプロパティに保存

しかし、Inertiaを利用すると上記のような手間をかける必要がなくUserController.phpで取得したユーザ一覧のデータusersをpropsとしてIndex.vueファイルに渡すことができます。

vueファイルでの処理

vueファイル内ではpropsとしてusersを受け取ることができるので追加の設定や処理は必要ありません。

propsで受け取ったusersをtemplateタグで展開することでブラウザに表示させることができます。


<template>
    <div class="p-4">

        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>

    </div>
</template>
<script>
    export default {
        props:{
            users: {
                type: Array,
            }
        }
    }
</script>
ユーザ一覧を表示
ユーザ一覧を表示

ユーザ一覧を表示するというシンプルな例でしたが、inertiaを利用することでバックエンドからのデータ取得の処理が大幅に楽になったことがわかるのではないでしょうか。

Vueのバージョン3からComposition APIのscript setupタグを利用することができます。先ほどの記述はOptions APIを利用して記述していますがComposition APIを利用することで下記のように記述することができます。


<script setup>
defineProps({
    users: Array,
});
</script>
<template>
    <div class="p-4">
        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>
    </div>
</template>

dashboardへのリンク設定

dashboardへのリンクを設定したい場合は、aタグではなくLinkタグを利用することができます。Linkタグを利用するためにはimportが必要となります。


<script setup>
import { Link } from "@inertiajs/inertia-vue3";
defineProps({
    users: Array,
});
</script>
<template>
    <header>
        <ul>
            <li><Link href="/dashboard">Dashboard</Link></li>
        </ul>
    </header>

    <div class="p-4">
        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>
    </div>
</template>

Linkを使用するとページをリロードすることなくdashboardの内容が画面に表示されます。ユーザのログインが完了している状態で行ってください。

aタグの場合はページを移動する場合にはページ全体を読み込む必要がありますがLinkタグを利用している場合は更新が必要な箇所のみJavaScript(Vue)によって更新が行われるためページの移動をスムーズに行うことができます。

まとめ

非常に短い文書でしたが本文書から以下のことが理解できました。

  • Laravel8, 9ではJetStreamパッケージを利用することでInertia.jsの特別な設定を行うことなくすぐに利用できる
  • JetStream環境下のInertia.jsを利用する場合にはVueを使ってブラウザに表示する画面を作成する
  • Vueファイルで利用するデータはLaravelの従来の方法と同じ方法でデータを取得してVueにはpropsを経由して渡す
  • Bladeファイルとは異なり、VueファイルはJavaScriptなので内容を更新するとJavaScriptのビルドが必要
  • Linkタグを利用することでページの移動をスムーズに行うことができる

本文書の内容だけではInertia.jsが何者かということは少しは理解できたと思います。下記の文章ではinertiaを利用してCRUD処理を説明しているのでさらに理解を深めたい場合はおすすめです。