Inertiaを除外!Laravel Breeze + Vue 3で「あの頃のような」シンプル開発する方法

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、この間ツイッターを眺めていると Vue3の衰退を招いたのは<script setup>とCompositionAPIかもしれない という考察 という話題になったブログ記事が流れてきました。

個人的にはComposition APIもお仕事では使いますが、正直「よっぽど大規模じゃない限りオーバースペックだったりしないのかな…🤔」とも思ったりもするので、共感する部分が多かったです。

やっぱり、Vue 2の「シンプル&強力」の残像が残っているんです(笑)

そして、そんな影響もあり思いついたのが「Laravel Breeze で Vue 3 は使うけど、Inertiaは使わないシンプル環境をつくってみたい」というものでした。

【追記:2023.8.14】
こちら、読んでいただいた方に誤解を与えてしまっていたようでした。
上記は「ビルドするのはnpmパッケージのみで、コードはビルドしない」という意味になります。混乱させてしまって申し訳ないです…😅

こちらも、viteでゴリゴリにビルドせす、各ページにVueのコードを書くという「シンプル・ウェイ」をしたくなったんですね。(← これだときっと会社も技術者を採用しやすいはず!)

Alpine.jsもありなんですが、コンポーネントを多用する場合はVueの方がいいかなという印象でした。

そこで❗

今回は「Laravel Breeze + Vue 3(でも、Inertiaは抜きね)」という開発環境を作ってみたいと思います。

ぜひ何かの参考になりましたら嬉しいです😄✨

「私の自転車は段切り替えが
ついてませんが、
私の足にはついてます。3段階ね👍」

やりたいこと

今回はやりたいことを以下にまとめてみました。

  • Laravel Breezeでログイン機能 & Vue 3 が使えるようにする
  • ただし、Inertia.js は使わない
  • つまり、vite は js や css をひとつにまとめるだけに使う(watch も使わない)
  • でも、axios とか TailwindCSS は使いたい

つまり、とにかくInertia.jsを除外したいというパターンです。(コレ、需要あるのかちょっと心配ですね…😂)

前提として

ということで、Laravel Breezeでログイン機能がインストールされていて、さらにそのインストールがVueパターンであることが前提です。

つまり、以下のコマンドが実行されていることが前提です。

composer require laravel/breeze --dev

# 👇 ここ
php artisan breeze:install vue

php artisan migrate
npm install
npm run dev

では、今回も楽しくやっていきましょう❗

Vite の設定ファイルを変更する

まず、Inertia抜きのvueを使うときに問題になるのが「ビルド方法」、つまりviteの設定です。(つまり、ビルド自体は使います)

そこで、以下のように設定ファイルを変更しておきましょう。

vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: [ // 👈 ここを変更しました
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: { // 👈 ここを追加しました
        alias: {
            vue: 'vue/dist/vue.esm-browser.prod.js',
        },
    },
});

app.js を変更する

次に、ビルドする際に使われるapp.jsを変更します。

Vue + Inertia」パターンでLaravel Breezeをインストールすると、この中にはInertiaの設定コードが含まれていますが不要なので全削除します。

import './bootstrap';
import '../css/app.css';

import { createApp } from 'vue';
window.createApp = createApp;

// 元からある、これ以降のコードはすべて削除 or コメントアウト

ちなみに、bootstrapが読み込まれているので、いつもどおりaxiosも使えます❗

また、cssに関しては今回は変更する必要はありませんが、パッケージをインストールしたり、改造したい場合は同様に以下のファイルを変更してviteでビルドしてください。

resources/css/app.css

独自のBladeディレクティブをつくる

これは次の項目で使うのですが、「Vue + Inertia」パターンでインストールすると@vite()というディレクティブをBladeファイル内で呼び出すと「js や css のタグを用意してくれる」ことになります。

ただ、これが厄介なんです…

というのも、この@viteを呼び出した場合のJavaScript用タグは以下のように「preload」「modulepreload」「module」といった通常の呼び出し方ではないため実行ができないのです。

<link rel="preload" as="style" href="http://vue-build.test/build/assets/app-ee30c653.css" />
<link rel="modulepreload" href="http://vue-build.test/build/assets/app-346cb035.js" />
<link rel="stylesheet" href="http://vue-build.test/build/assets/app-ee30c653.css" />
<script type="module" src="http://vue-build.test/build/assets/app-346cb035.js"></script>

そこで、「このタグの代わりを独自につくっちゃおう❗」というのがこの項目の目的です。

では、以下のコードを追加してください。

app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade; // 👈 ここを追加しました
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // 👇 ここを追加しました
        Blade::directive('assets', function (string $expression) {

            $manifest_path = public_path('build/manifest.json');

            return '
                <?php

                    $manifest_data = json_decode(
                        file_get_contents("'. $manifest_path .'"),
                        true
                    );
                    echo "<script src=\\"/build/". $manifest_data["resources/js/app.js"]["file"] ."\\"></script>";
                    echo "<link rel=\\"stylesheet\\" href=\\"/build/". $manifest_data["resources/js/app.js"]["css"][0] ."\\">";

                ?>
            ';

        });
    }
}

【追記:2023.10.10】
以前のコードではビルドしてもビューにキャッシュが残ってしまい、変更が適用されないので変更しました。

つまり、storage/framework/viewsフォルダ内に実際に出力されるキャッシュ用のコードは以下のようになります。(これなら毎回データ取得するのでキャッシュされることはありません👍)

<?php

    $manifest_data = json_decode(
        file_get_contents("(Laravelまでのパス)/public/build/manifest.json"),
        true
    );
    echo "<script src=\"/build/". $manifest_data["resources/js/app.js"]["file"] ."\"></script>";
    echo "<link rel=\"stylesheet\" href=\"/build/". $manifest_data["resources/js/app.js"]["css"][0] ."\">";

?>

これで、@assetsBlade内で使えるようになりました。

また、ビルドするたびにランダムにファイル名が変わりますが、public/build/manifest.jsonから最新のファイル名を取得しているので何度ビルドしなおしても問題はありません👍

レイアウトファイルをつくる

続いて、「Vue + Inertia」では存在していないBladeの「レイアウトファイル」を作成しましょう。

resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Fonts -->
    <link rel="preconnect" href="https://fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />

    <!-- Scripts -->
    @assets
</head>
<body class="font-sans antialiased">

    @yield('content')
    @yield('script')

</body>
</html>

これで「Inertia 抜き」でVue 3を使う準備が完了しました❗

ビュー&ルートをつくる

では、最期にテスト用のビューとルートを作ってみましょう。

resources/views/vue_without_inertia.blade.php

@extends('layouts.app')

@section('content')

    <div id="app" class="p-5">
        <div class="bg-red-500 p-1" v-text="greeting"></div>
    </div>

@endsection

@section('script')

    <script>

        createApp({
            data() {
                return {
                    greeting: 'おっはよ!'
                }
            },
        }).mount('#app');

    </script>

@endsection

お気づきのとおり、このコードはInertiaは使っていませんし、何ならVue 2形式で書いているので「シンプル&強力」になっています。

そして、以下のルートも追加してください。

routes/web.php

Route::get('vue_without_inertia', fn() => view('vue_without_inertia'));

はい❗
これですべての作業が完了しました。

お疲れ様でした😄✨

おまけ: HTMLのコードが変更されない沼にはまったら

おそらくシンプルにキャッシュが効いてるだけです。
以下のコマンドを実行してください。(実はコレ、私です…😅)

php artisan view:clear

テストしてみる

では、実際にテストしてみましょう❗

まずはviteでビルドします。
以下のコマンドを実行してください。

npm run build

すると、自動でviteがいい感じにjscssファイルを一つに固めてくれます。(vite早いですね👍)

では、この状態でブラウザを使い、「https://******/vue_without_inertia」にアクセスしてみましょう。

どうなるでしょうか・・・・・・

はい❗「おっはよ!」というテキストはJavaScript内にありましたが、Vueによって表示されています。

すべて成功です😄✨

企業様へのご提案

(2023.7.20 現在の)Laravel BreezeではVueを使おうとすると、自動的にInertiaと統合されてしまうため、それまで培ったVueのコードの書き方を根本的に変更せざるを得ない状況でした。

しかし、今回のテクニックを使うことで過去のコードを再利用しやすくなりますし、なにより移行にあたって学習コストはほとんど発生しません。

もし、そういった状況でお困りでしたらいつでもお気軽にご相談ください。
お待ちしております。😄✨

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回は「Laravel + Vue(Inertia 抜き)」の環境をつくってみました。

もちろん「Vue + Inertia」を使う場合のメリットもたくさんあるとは思うのですが、シンプルにいきたい場合は確実にオーバースペックになるので、選別が難しいところですね。

そう考えると、Laravel Breezeをインストールするとき「vue」に「–no-inertia」みたいな選択肢を用意してくれると嬉しいんですけど、多分プルリクエストしても拒否されそうですね😂

ということで、ぜひ皆さんもやってみてくださいね。

ではでは〜❗

「週末は朝から
出かける影響で、
夕食後と寝ちゃいます😂」

このエントリーをはてなブックマークに追加       follow us in feedly