🙆‍♀️

Laravel Viteでvueにimport.meta.url経由でクエリパラメータを渡す

2024/08/07に公開

import.meta.url

モジュールの場合、import.metaオブジェクトを使用して自身のメタ情報にアクセスできる。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/import.meta

そのため、

<script type="module" src="app.js?someURLInfo=5"></script>

このとき、app.js内ではimport.meta.urlで自身のURLをクエリパラメータやハッシュ付きで取得することができる。
つまり、

new URL(import.meta.url).searchParams.get('someURLInfo') // '5';

のようにしてクエリパラメータ経由で値を渡すことができる。

Laravel Viteでの利用

さて、Laravel Viteでこれを利用しようと思うと、jsの読み込みは

@vite('resources/js/app.js')

のように書くので

@vite('resources/js/app.js?someURLInfo=5')

とすれば良さそうだが、これでは上手く行かない。
正確には、npm run devで開発サーバを起動してローカルで開発する分には動くが、npm run buildを実行して本番にデプロイすると生成されたjsファイルの参照に失敗して500エラーになる。

そこでLaravelのドキュメントを読むと、Viteプラグインには高度なカスタマイズとしてパスの値を変更するcreateAssetPathsUsingというメソッドが用意されているようだ。

https://readouble.com/laravel/11.x/ja/vite.html#advanced-customization

つまりこう書けば良いらしい。

    {{
        Vite::withEntryPoints(['resources/js/app.js'])
            ->createAssetPathsUsing(function (string $path, ?bool $secure) {
                return "/{$path}?someURLInfo=5";
            })
    }}

ところが、これはこれで今度は本番では上手く動くがnpm run devで開発サーバを起動してローカルで開発しようとするとcreateAssetPathsUsingで設定した事が無視されてしまい上手く行かない。

しかし裏を返せば片方は本番で上手く動き、片方は開発サーバで上手く動く訳だから、両方を組み合わせれば良さそうだ。そのためには開発サーバを起動して開発中なのかどうかが判別出来れば良い。
ドキュメントを読むと幸いViteクラスにはそのようなメソッドが用意されている。
isRunningHotがそれだ。

https://laravel.com/api/11.x/Illuminate/Support/Facades/Vite.html#method_isRunningHot

つまりこうだ。

TL;DR

index.blade.php
// Viteのエイリアスを設定しておくこと
// 'Vite' => \Illuminate\Support\Facades\Vite::class,
@if(Vite::isRunningHot())
@vite('resources/js/app.js?someURLInfo=5')
@else
    {{
        Vite::withEntryPoints(['resources/js/app.js'])
            ->createAssetPathsUsing(function (string $path, ?bool $secure) {
                return "/{$path}?someURLInfo=5";
            })
    }}
@endif

Discussion