
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、この間ツイッターを眺めていると 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] ."\">";
?>
これで、@assets
がBlade
内で使えるようになりました。
また、ビルドするたびにランダムにファイル名が変わりますが、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
がいい感じにjs
、css
ファイルを一つに固めてくれます。(vite
早いですね)
では、この状態でブラウザを使い、「https://******/vue_without_inertia」にアクセスしてみましょう。
どうなるでしょうか・・・・・・
はい「おっはよ!」というテキストは
JavaScript
内にありましたが、Vue
によって表示されています。
すべて成功です
企業様へのご提案
(2023.7.20 現在の)Laravel Breeze
ではVue
を使おうとすると、自動的にInertia
と統合されてしまうため、それまで培ったVue
のコードの書き方を根本的に変更せざるを得ない状況でした。
しかし、今回のテクニックを使うことで過去のコードを再利用しやすくなりますし、なにより移行にあたって学習コストはほとんど発生しません。
もし、そういった状況でお困りでしたらいつでもお気軽にご相談ください。
お待ちしております。
おわりに
ということで、今回は「Laravel + Vue(Inertia 抜き)」の環境をつくってみました。
もちろん「Vue + Inertia」を使う場合のメリットもたくさんあるとは思うのですが、シンプルにいきたい場合は確実にオーバースペックになるので、選別が難しいところですね。
そう考えると、Laravel Breeze
をインストールするとき「vue」に「–no-inertia」みたいな選択肢を用意してくれると嬉しいんですけど、多分プルリクエストしても拒否されそうですね
ということで、ぜひ皆さんもやってみてくださいね。
ではでは〜
「週末は朝から
出かける影響で、
夕食後と寝ちゃいます」