コンテンツへスキップ

アセットのバンドル(Vite)

イントロダクション

Viteは、非常に高速な開発環境を提供し、本番用にコードをバンドルする最新のフロントエンドビルドツールです。Laravelでアプリケーションを構築する場合、通常、Viteを使用してアプリケーションのCSSおよびJavaScriptファイルを本番環境に対応したアセットにバンドルします。

Laravelは、開発と本番用にアセットをロードするための公式プラグインとBladeディレクティブを提供することにより、Viteとシームレスに統合します。

Laravel Mixを実行していますか?新しいLaravelインストールでは、ViteがLaravel Mixを置き換えました。Mixのドキュメントについては、Laravel MixのWebサイトをご覧ください。Viteに切り替えたい場合は、移行ガイドを参照してください。

ViteとLaravel Mixの選択

Viteへ移行する前、新しいLaravelアプリケーションはアセットをバンドルする際にwebpackを搭載したMixを利用していました。Viteは、リッチなJavaScriptアプリケーションを構築する際に、より速く、より生産的なエクスペリエンスを提供することに重点を置いています。Inertiaのようなツールで開発したものを含め、シングルページアプリケーション(SPA)を開発している場合、Viteは最適な選択肢です。

Viteは、Livewireを使用しているものを含め、JavaScriptを「振りかけた」従来のサーバサイドレンダリングアプリケーションでもうまく機能します。しかし、JavaScriptアプリケーションで直接参照されていない任意のアセットをビルドにコピーする機能など、Laravel Mixがサポートする一部の機能がありません。

Mixへの再移行

Viteスカフォールドを使用して新しいLaravelアプリケーションを開始しましたが、Laravel Mixとwebpackに戻す必要がありますか?問題ありません。ViteからMixへの移行に関する公式ガイドを参照してください。

インストールとセットアップ

以下のドキュメントでは、Laravel Viteプラグインを手動でインストールして設定する方法について説明します。しかし、Laravelのスターターキットには、これらすべてのスカフォールドがすでに含まれており、LaravelとViteを始めるための最速の方法です。

Nodeのインストール

ViteとLaravelプラグインを実行する前に、Node.js(16+)とNPMがインストールされていることを確認する必要があります。

1node -v
2npm -v

Nodeの公式ウェブサイトから簡単なグラフィカルインストーラを使用して、最新バージョンのNodeとNPMを簡単にインストールできます。または、Laravel Sailを使用している場合は、Sailを介してNodeとNPMを呼び出すことができます。

1./vendor/bin/sail node -v
2./vendor/bin/sail npm -v

ViteとLaravelプラグインのインストール

Laravelの新規インストール環境には、アプリケーションのディレクトリ構造のルートにpackage.jsonファイルがあります。デフォルトのpackage.jsonファイルには、ViteとLaravelプラグインを使い始めるために必要なものがすべてすでに含まれています。NPMを介してアプリケーションのフロントエンドの依存関係をインストールします。

1npm install

Viteの設定

Viteは、プロジェクトのルートにあるvite.config.jsファイルを介して設定します。このファイルは、必要に応じて自由にカスタマイズでき、@vitejs/plugin-vue@vitejs/plugin-reactなど、アプリケーションに必要な他のプラグインをインストールすることもできます。

Laravel Viteプラグインでは、アプリケーションのエントリポイントを指定する必要があります。これらはJavaScriptまたはCSSファイルであり、TypeScript、JSX、TSX、Sassなどのプリプロセス言語を含めることができます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel([
7 'resources/css/app.css',
8 'resources/js/app.js',
9 ]),
10 ],
11});

Inertiaを使用して構築されたアプリケーションを含むSPAを構築している場合、ViteはCSSエントリポイントなしで最適に機能します。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel([
7 'resources/css/app.css',
8 'resources/js/app.js',
9 ]),
10 ],
11});

代わりに、JavaScriptを介してCSSをインポートする必要があります。通常、これはアプリケーションのresources/js/app.jsファイルで行います。

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

Laravelプラグインは、複数のエントリポイントやSSRエントリポイントなどの高度な設定オプションもサポートしています。

安全な開発サーバの利用

ローカル開発WebサーバがHTTPS経由でアプリケーションを提供している場合、Vite開発サーバへの接続で問題が発生する可能性があります。

Laravel Herdを使用してサイトを保護している場合、またはLaravel Valetを使用してアプリケーションに対してsecureコマンドを実行した場合、Laravel Viteプラグインは生成されたTLS証明書を自動的に検出して使用します。

アプリケーションのディレクトリ名と一致しないホストを使用してサイトを保護した場合、アプリケーションのvite.config.jsファイルでホストを手動で指定できます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 // ...
8 detectTls: 'my-app.test',
9 }),
10 ],
11});

別のWebサーバを使用する場合は、信頼できる証明書を生成し、生成された証明書を使用するようにViteを手動で設定する必要があります。

1// ...
2import fs from 'fs';
3 
4const host = 'my-app.test';
5 
6export default defineConfig({
7 // ...
8 server: {
9 host,
10 hmr: { host },
11 https: {
12 key: fs.readFileSync(`/path/to/${host}.key`),
13 cert: fs.readFileSync(`/path/to/${host}.crt`),
14 },
15 },
16});

システム用の信頼できる証明書を生成できない場合は、@vitejs/plugin-basic-sslプラグインをインストールして設定できます。信頼できない証明書を使用する場合、npm run devコマンドを実行するときにコンソールの「Local」リンクをたどり、ブラウザでViteの開発サーバの証明書警告を受け入れる必要があります。

WSL2上のSailでの開発サーバの実行

Windows Subsystem for Linux 2 (WSL2)上のLaravel Sail内でVite開発サーバを実行する場合、ブラウザが開発サーバと通信できるように、vite.config.jsファイルに以下の設定を追加する必要があります。

1// ...
2 
3export default defineConfig({
4 // ...
5 server: {
6 hmr: {
7 host: 'localhost',
8 },
9 },
10});

開発サーバの実行中にファイルの変更がブラウザに反映されない場合は、Viteのserver.watch.usePollingオプションも設定する必要があるかもしれません。

スクリプトとスタイルの読み込み

Viteのエントリポイントを設定したら、アプリケーションのルートテンプレートの<head>に追加する@vite() Bladeディレクティブでそれらを参照できるようになりました。

1<!DOCTYPE html>
2<head>
3 {{-- ... --}}
4 
5 @vite(['resources/css/app.css', 'resources/js/app.js'])
6</head>

JavaScriptを介してCSSをインポートしている場合は、JavaScriptエントリポイントを含めるだけで済みます。

1<!DOCTYPE html>
2<head>
3 {{-- ... --}}
4 
5 @vite('resources/js/app.js')
6</head>

@viteディレクティブは、Vite開発サーバを自動的に検出し、ホットモジュールリプレースメントを有効にするためにViteクライアントを挿入します。ビルドモードでは、このディレクティブはインポートされたCSSを含む、コンパイルされバージョン管理されたアセットをロードします。

必要に応じて、@viteディレクティブを呼び出すときに、コンパイル済みアセットのビルドパスを指定することもできます。

1<!doctype html>
2<head>
3 {{-- Given build path is relative to public path. --}}
4 
5 @vite('resources/js/app.js', 'vendor/courier/build')
6</head>

インラインアセット

アセットのバージョン管理されたURLにリンクするのではなく、アセットの生コンテンツを含める必要がある場合があります。たとえば、HTMLコンテンツをPDFジェネレータに渡すときに、アセットコンテンツをページに直接含める必要があるかもしれません。Viteファサードが提供するcontentメソッドを使用して、Viteアセットのコンテンツを出力できます。

1@use('Illuminate\Support\Facades\Vite')
2 
3<!doctype html>
4<head>
5 {{-- ... --}}
6 
7 <style>
8 {!! Vite::content('resources/css/app.css') !!}
9 </style>
10 <script>
11 {!! Vite::content('resources/js/app.js') !!}
12 </script>
13</head>

Viteの実行

Viteを実行するには2つの方法があります。devコマンドを介して開発サーバを実行できます。これは、ローカルで開発しているときに役立ちます。開発サーバはファイルの変更を自動的に検出し、開いているブラウザウィンドウに即座に反映します。

または、buildコマンドを実行すると、アプリケーションのアセットがバージョン管理およびバンドルされ、本番環境にデプロイする準備が整います。

1# Run the Vite development server...
2npm run dev
3 
4# Build and version the assets for production...
5npm run build

WSL2上のSailで開発サーバを実行している場合は、追加の設定オプションが必要になる場合があります。

JavaScriptの操作

エイリアス

デフォルトで、Laravelプラグインは、アプリケーションのアセットを便利にインポートし、すぐに使い始められるようにするための一般的なエイリアスを提供します。

1{
2 '@' => '/resources/js'
3}

vite.config.js設定ファイルに独自のエイリアスを追加することで、'@'エイリアスを上書きできます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel(['resources/ts/app.tsx']),
7 ],
8 resolve: {
9 alias: {
10 '@': '/resources/ts',
11 },
12 },
13});

Vue

Vueフレームワークを使用してフロントエンドを構築したい場合は、@vitejs/plugin-vueプラグインもインストールする必要があります。

1npm install --save-dev @vitejs/plugin-vue

次に、vite.config.js設定ファイルにプラグインを含めることができます。LaravelでVueプラグインを使用する場合、いくつかの追加オプションが必要になります。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3import vue from '@vitejs/plugin-vue';
4 
5export default defineConfig({
6 plugins: [
7 laravel(['resources/js/app.js']),
8 vue({
9 template: {
10 transformAssetUrls: {
11 // The Vue plugin will re-write asset URLs, when referenced
12 // in Single File Components, to point to the Laravel web
13 // server. Setting this to `null` allows the Laravel plugin
14 // to instead re-write asset URLs to point to the Vite
15 // server instead.
16 base: null,
17 
18 // The Vue plugin will parse absolute URLs and treat them
19 // as absolute paths to files on disk. Setting this to
20 // `false` will leave absolute URLs un-touched so they can
21 // reference assets in the public directory as expected.
22 includeAbsolute: false,
23 },
24 },
25 }),
26 ],
27});

Laravelのスターターキットには、適切なLaravel、Vue、Viteの設定がすでに含まれています。これらのスターターキットは、Laravel、Vue、Viteを始めるための最速の方法です。

React

Reactフレームワークを使用してフロントエンドを構築したい場合は、@vitejs/plugin-reactプラグインもインストールする必要があります。

1npm install --save-dev @vitejs/plugin-react

次に、vite.config.js設定ファイルにプラグインを含めることができます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3import react from '@vitejs/plugin-react';
4 
5export default defineConfig({
6 plugins: [
7 laravel(['resources/js/app.jsx']),
8 react(),
9 ],
10});

JSXを含むファイルには.jsxまたは.tsx拡張子が付いていることを確認し、必要に応じて上記で示したようにエントリポイントを更新することを忘れないでください。

また、既存の@viteディレクティブと一緒に、追加の@viteReactRefresh Bladeディレクティブを含める必要があります。

1@viteReactRefresh
2@vite('resources/js/app.jsx')

@viteReactRefreshディレクティブは、@viteディレクティブの前に呼び出す必要があります。

Laravelのスターターキットには、適切なLaravel、React、Viteの設定がすでに含まれています。これらのスターターキットは、Laravel、React、Viteを始めるための最速の方法です。

Inertia

Laravel Viteプラグインは、Inertiaページコンポーネントを解決するのに役立つ便利なresolvePageComponent関数を提供します。以下はVue 3でヘルパーを使用した例です。ただし、Reactなどの他のフレームワークでもこの関数を利用できます。

1import { createApp, h } from 'vue';
2import { createInertiaApp } from '@inertiajs/vue3';
3import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
4 
5createInertiaApp({
6 resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
7 setup({ el, App, props, plugin }) {
8 createApp({ render: () => h(App, props) })
9 .use(plugin)
10 .mount(el)
11 },
12});

InertiaでViteのコード分割機能を使用している場合は、アセットのプリフェッチを設定することをお勧めします。

Laravelのスターターキットには、適切なLaravel、Inertia、Viteの設定がすでに含まれています。これらのスターターキットは、Laravel、Inertia、Viteを始めるための最速の方法です。

URL処理

Viteを使用してアプリケーションのHTML、CSS、またはJSでアセットを参照する場合、考慮すべき注意点がいくつかあります。まず、絶対パスでアセットを参照すると、Viteはビルドにアセットを含めません。したがって、アセットがパブリックディレクトリで使用可能であることを確認する必要があります。専用のCSSエントリポイントを使用する場合は、絶対パスの使用を避けるべきです。なぜなら、開発中にブラウザはパブリックディレクトリからではなく、CSSがホストされているVite開発サーバからこれらのパスを読み込もうとするからです。

相対的なアセットパスを参照する場合は、パスが参照されているファイルからの相対パスであることを覚えておく必要があります。相対パスを介して参照されるアセットはすべて、Viteによって書き換え、バージョン管理、およびバンドルされます。

次のプロジェクト構造を考えてみましょう。

1public/
2 taylor.png
3resources/
4 js/
5 Pages/
6 Welcome.vue
7 images/
8 abigail.png

次の例は、Viteが相対URLと絶対URLをどのように扱うかを示しています。

1<!-- This asset is not handled by Vite and will not be included in the build -->
2<img src="/taylor.png">
3 
4<!-- This asset will be re-written, versioned, and bundled by Vite -->
5<img src="../../images/abigail.png">

スタイルシートの操作

ViteのCSSサポートの詳細については、Viteのドキュメントで学ぶことができます。TailwindなどのPostCSSプラグインを使用している場合は、プロジェクトのルートにpostcss.config.jsファイルを作成すると、Viteが自動的にそれを適用します。

1export default {
2 plugins: {
3 tailwindcss: {},
4 autoprefixer: {},
5 },
6};

Laravelのスターターキットには、適切なTailwind、PostCSS、Viteの設定がすでに含まれています。または、スターターキットを使用せずにTailwindとLaravelを使用したい場合は、TailwindのLaravel用インストールガイドを確認してください。

Bladeとルートの操作

Viteによる静的アセットの処理

JavaScriptまたはCSSでアセットを参照する場合、Viteは自動的にそれらを処理し、バージョン管理します。さらに、Bladeベースのアプリケーションを構築する場合、ViteはBladeテンプレートでのみ参照する静的アセットを処理し、バージョン管理することもできます。

ただし、これを実現するには、静的アセットをアプリケーションのエントリポイントにインポートして、Viteにアセットを認識させる必要があります。たとえば、resources/imagesに保存されているすべての画像とresources/fontsに保存されているすべてのフォントを処理してバージョン管理したい場合は、アプリケーションのresources/js/app.jsエントリポイントに以下を追加する必要があります。

1import.meta.glob([
2 '../images/**',
3 '../fonts/**',
4]);

これらのアセットは、npm run buildを実行するとViteによって処理されるようになります。その後、Vite::assetメソッドを使用してBladeテンプレートでこれらのアセットを参照でき、これにより特定のアセットのバージョン管理されたURLが返されます。

1<img src="{{ Vite::asset('resources/images/logo.png') }}">

保存時のリフレッシュ

アプリケーションがBladeを使用した従来のサーバサイドレンダリングで構築されている場合、Viteは、アプリケーションのビューファイルに変更を加えたときにブラウザを自動的に更新することで、開発ワークフローを改善できます。開始するには、refreshオプションをtrueとして指定するだけです。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 // ...
8 refresh: true,
9 }),
10 ],
11});

refreshオプションがtrueの場合、npm run devを実行しているときに以下のディレクトリ内のファイルを保存すると、ブラウザがページ全体をリフレッシュします。

  • app/Livewire/**
  • app/View/Components/**
  • lang/**
  • resources/lang/**
  • resources/views/**
  • routes/**

routes/**ディレクトリを監視することは、Ziggyを利用してアプリケーションのフロントエンド内でルートリンクを生成している場合に便利です。

これらのデフォルトパスがニーズに合わない場合は、監視する独自のパスのリストを指定できます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 // ...
8 refresh: ['resources/views/**'],
9 }),
10 ],
11});

内部では、Laravel Viteプラグインはvite-plugin-full-reloadパッケージを使用しており、この機能の動作を微調整するための高度な設定オプションをいくつか提供しています。このレベルのカスタマイズが必要な場合は、config定義を提供できます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 // ...
8 refresh: [{
9 paths: ['path/to/watch/**'],
10 config: { delay: 300 }
11 }],
12 }),
13 ],
14});

エイリアス

JavaScriptアプリケーションでは、頻繁に参照されるディレクトリへのエイリアスを作成するのが一般的です。しかし、Illuminate\Support\Facades\Viteクラスのmacroメソッドを使用して、Bladeで使用するエイリアスを作成することもできます。通常、「マクロ」はサービスプロバイダbootメソッド内で定義する必要があります。

1/**
2 * Bootstrap any application services.
3 */
4public function boot(): void
5{
6 Vite::macro('image', fn (string $asset) => $this->asset("resources/images/{$asset}"));
7}

マクロを定義すると、テンプレート内で呼び出すことができます。たとえば、上記で定義したimageマクロを使用して、resources/images/logo.pngにあるアセットを参照できます。

1<img src="{{ Vite::image('logo.png') }}" alt="Laravel Logo">

アセットのプリフェッチ

Viteのコード分割機能を使用してSPAを構築する場合、必要なアセットは各ページナビゲーションで取得されます。この動作により、UIレンダリングが遅れる可能性があります。これが選択したフロントエンドフレームワークで問題になる場合、Laravelは最初のページロード時にアプリケーションのJavaScriptおよびCSSアセットを積極的にプリフェッチする機能を提供します。

サービスプロバイダbootメソッドでVite::prefetchメソッドを呼び出すことで、Laravelにアセットを積極的にプリフェッチするように指示できます。

1<?php
2 
3namespace App\Providers;
4 
5use Illuminate\Support\Facades\Vite;
6use Illuminate\Support\ServiceProvider;
7 
8class AppServiceProvider extends ServiceProvider
9{
10 /**
11 * Register any application services.
12 */
13 public function register(): void
14 {
15 // ...
16 }
17 
18 /**
19 * Bootstrap any application services.
20 */
21 public function boot(): void
22 {
23 Vite::prefetch(concurrency: 3);
24 }
25}

上記の例では、アセットは各ページロード時に最大3の同時ダウンロードでプリフェッチされます。アプリケーションのニーズに合わせて同時実行数を変更したり、アプリケーションがすべてのアセットを一度にダウンロードする必要がある場合は同時実行数制限を指定しないこともできます。

1/**
2 * Bootstrap any application services.
3 */
4public function boot(): void
5{
6 Vite::prefetch();
7}

デフォルトでは、プリフェッチはページのloadイベントが発生したときに開始されます。プリフェッチが開始されるタイミングをカスタマイズしたい場合は、Viteがリッスンするイベントを指定できます。

1/**
2 * Bootstrap any application services.
3 */
4public function boot(): void
5{
6 Vite::prefetch(event: 'vite:prefetch');
7}

上記のコードでは、windowオブジェクトでvite:prefetchイベントを手動でディスパッチしたときにプリフェッチが開始されるようになりました。たとえば、ページが読み込まれてから3秒後にプリフェッチを開始させることができます。

1<script>
2 addEventListener('load', () => setTimeout(() => {
3 dispatchEvent(new Event('vite:prefetch'))
4 }, 3000))
5</script>

カスタムベースURL

Viteでコンパイルされたアセットが、CDNなどを介してアプリケーションとは別のドメインにデプロイされている場合は、アプリケーションの.envファイル内でASSET_URL環境変数を指定する必要があります。

1ASSET_URL=https://cdn.example.com

アセットURLを設定すると、アセットへの書き換えられたすべてのURLに、設定した値がプレフィックスとして付きます。

1https://cdn.example.com/build/assets/app.9dce8d17.js

絶対URLはViteによって書き換えられないため、プレフィックスが付かないことに注意してください。

環境変数

環境変数をJavaScriptに注入するには、アプリケーションの.envファイルでVITE_プレフィックスを付けます。

1VITE_SENTRY_DSN_PUBLIC=http://example.com

import.meta.envオブジェクトを介して注入された環境変数にアクセスできます。

1import.meta.env.VITE_SENTRY_DSN_PUBLIC

テストでのViteの無効化

LaravelのVite統合は、テストの実行中にアセットを解決しようとします。そのため、Vite開発サーバを実行するか、アセットをビルドする必要があります。

テスト中にViteをモックしたい場合は、withoutViteメソッドを呼び出すことができます。これは、LaravelのTestCaseクラスを拡張するテストで利用可能です。

1test('without vite example', function () {
2 $this->withoutVite();
3 
4 // ...
5});
1use Tests\TestCase;
2 
3class ExampleTest extends TestCase
4{
5 public function test_without_vite_example(): void
6 {
7 $this->withoutVite();
8 
9 // ...
10 }
11}

すべてのテストでViteを無効にしたい場合は、基本のTestCaseクラスのsetUpメソッドからwithoutViteメソッドを呼び出すことができます。

1<?php
2 
3namespace Tests;
4 
5use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
6 
7abstract class TestCase extends BaseTestCase
8{
9 protected function setUp(): void
10 {
11 parent::setUp();
12 
13 $this->withoutVite();
14 }
15}

サーバサイドレンダリング(SSR)

Laravel Viteプラグインを使用すると、Viteでサーバサイドレンダリングを簡単にセットアップできます。まず、resources/js/ssr.jsにSSRエントリポイントを作成し、Laravelプラグインに設定オプションを渡してエントリポイントを指定します。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 input: 'resources/js/app.js',
8 ssr: 'resources/js/ssr.js',
9 }),
10 ],
11});

SSRエントリポイントの再ビルドを忘れないように、アプリケーションのpackage.jsonの「build」スクリプトを拡張してSSRビルドを作成することをお勧めします。

1"scripts": {
2 "dev": "vite",
3 "build": "vite build"
4 "build": "vite build && vite build --ssr"
5}

次に、SSRサーバをビルドして起動するには、以下のコマンドを実行します。

1npm run build
2node bootstrap/ssr/ssr.js

InertiaでSSRを使用している場合は、代わりにinertia:start-ssr Artisanコマンドを使用してSSRサーバを起動できます。

1php artisan inertia:start-ssr

Laravelのスターターキットには、適切なLaravel、Inertia SSR、Viteの設定がすでに含まれています。これらのスターターキットは、Laravel、Inertia SSR、Viteを始めるための最速の方法です。

ScriptおよびStyleタグ属性

コンテンツセキュリティポリシー(CSP) Nonce

コンテンツセキュリティポリシーの一部として、scriptタグとstyleタグにnonce属性を含めたい場合は、カスタムミドルウェア内でuseCspNonceメソッドを使用してnonceを生成または指定できます。

1<?php
2 
3namespace App\Http\Middleware;
4 
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\Vite;
8use Symfony\Component\HttpFoundation\Response;
9 
10class AddContentSecurityPolicyHeaders
11{
12 /**
13 * Handle an incoming request.
14 *
15 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
16 */
17 public function handle(Request $request, Closure $next): Response
18 {
19 Vite::useCspNonce();
20 
21 return $next($request)->withHeaders([
22 'Content-Security-Policy' => "script-src 'nonce-".Vite::cspNonce()."'",
23 ]);
24 }
25}

useCspNonceメソッドを呼び出すと、Laravelは生成されたすべてのscriptタグとstyleタグに自動的にnonce属性を含めます。

Laravelのスターターキットに含まれるZiggyの@routeディレクティブなど、他の場所でnonceを指定する必要がある場合は、cspNonceメソッドを使用して取得できます。

1@routes(nonce: Vite::cspNonce())

Laravelに使用させたいnonceがすでにある場合は、そのnonceをuseCspNonceメソッドに渡すことができます。

1Vite::useCspNonce($nonce);

サブリソース完全性(SRI)

Viteマニフェストにアセットのintegrityハッシュが含まれている場合、Laravelはサブリソース完全性を強制するために、生成するすべてのscriptタグとstyleタグに自動的にintegrity属性を追加します。デフォルトでは、Viteはマニフェストにintegrityハッシュを含めませんが、vite-plugin-manifest-sri NPMプラグインをインストールすることで有効にできます。

1npm install --save-dev vite-plugin-manifest-sri

次に、このプラグインをvite.config.jsファイルで有効にすることができます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3import manifestSRI from 'vite-plugin-manifest-sri';
4 
5export default defineConfig({
6 plugins: [
7 laravel({
8 // ...
9 }),
10 manifestSRI(),
11 ],
12});

必要に応じて、integrityハッシュが見つかるマニフェストキーをカスタマイズすることもできます。

1use Illuminate\Support\Facades\Vite;
2 
3Vite::useIntegrityKey('custom-integrity-key');

この自動検出を完全に無効にしたい場合は、useIntegrityKeyメソッドにfalseを渡すことができます。

1Vite::useIntegrityKey(false);

任意の属性

data-turbo-track属性など、scriptタグとstyleタグに追加の属性を含める必要がある場合は、useScriptTagAttributesメソッドとuseStyleTagAttributesメソッドを介して指定できます。通常、これらのメソッドはサービスプロバイダから呼び出す必要があります。

1use Illuminate\Support\Facades\Vite;
2 
3Vite::useScriptTagAttributes([
4 'data-turbo-track' => 'reload', // Specify a value for the attribute...
5 'async' => true, // Specify an attribute without a value...
6 'integrity' => false, // Exclude an attribute that would otherwise be included...
7]);
8 
9Vite::useStyleTagAttributes([
10 'data-turbo-track' => 'reload',
11]);

条件付きで属性を追加する必要がある場合は、アセットのソースパス、そのURL、そのマニフェストチャンク、およびマニフェスト全体を受け取るコールバックを渡すことができます。

1use Illuminate\Support\Facades\Vite;
2 
3Vite::useScriptTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
4 'data-turbo-track' => $src === 'resources/js/app.js' ? 'reload' : false,
5]);
6 
7Vite::useStyleTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
8 'data-turbo-track' => $chunk && $chunk['isEntry'] ? 'reload' : false,
9]);

Vite開発サーバの実行中は、$chunk$manifest引数はnullになります。

高度なカスタマイズ

LaravelのViteプラグインは、そのままでほとんどのアプリケーションで機能するはずの賢明な規約を使用しています。ただし、Viteの動作をカスタマイズする必要がある場合もあります。追加のカスタマイズオプションを有効にするために、@vite Bladeディレクティブの代わりに使用できる以下のメソッドとオプションを提供しています。

1<!doctype html>
2<head>
3 {{-- ... --}}
4 
5 {{
6 Vite::useHotFile(storage_path('vite.hot')) // Customize the "hot" file...
7 ->useBuildDirectory('bundle') // Customize the build directory...
8 ->useManifestFilename('assets.json') // Customize the manifest filename...
9 ->withEntryPoints(['resources/js/app.js']) // Specify the entry points...
10 ->createAssetPathsUsing(function (string $path, ?bool $secure) { // Customize the backend path generation for built assets...
11 return "https://cdn.example.com/{$path}";
12 })
13 }}
14</head>

次に、vite.config.jsファイル内で、同じ設定を指定する必要があります。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 hotFile: 'storage/vite.hot', // Customize the "hot" file...
8 buildDirectory: 'bundle', // Customize the build directory...
9 input: ['resources/js/app.js'], // Specify the entry points...
10 }),
11 ],
12 build: {
13 manifest: 'assets.json', // Customize the manifest filename...
14 },
15});

開発サーバのクロスオリジンリソース共有(CORS)

Vite開発サーバからアセットを取得する際にブラウザでクロスオリジンリソース共有(CORS)の問題が発生している場合は、カスタムオリジンに開発サーバへのアクセスを許可する必要があるかもしれません。ViteとLaravelプラグインを組み合わせることで、追加の設定なしに以下のオリジンが許可されます。

  • ::1
  • 127.0.0.1
  • localhost
  • *.test
  • *.localhost
  • プロジェクトの.envにあるAPP_URL

プロジェクトにカスタムオリジンを許可する最も簡単な方法は、アプリケーションのAPP_URL環境変数がブラウザでアクセスしているオリジンと一致することを確認することです。たとえば、https://my-app.laravelにアクセスしている場合は、.envをそれに合わせて更新する必要があります。

1APP_URL=https://my-app.laravel

複数のオリジンをサポートするなど、オリジンに対してよりきめ細かい制御が必要な場合は、Viteの包括的で柔軟な組み込みCORSサーバ設定を利用する必要があります。たとえば、プロジェクトのvite.config.jsファイルのserver.cors.origin設定オプションで複数のオリジンを指定できます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 input: 'resources/js/app.js',
8 refresh: true,
9 }),
10 ],
11 server: {
12 cors: {
13 origin: [
14 'https://backend.laravel',
15 'http://admin.laravel:8566',
16 ],
17 },
18 },
19});

正規表現パターンを含めることもできます。これは、*.laravelのような特定のトップレベルドメインのすべてのオリジンを許可したい場合に役立ちます。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 input: 'resources/js/app.js',
8 refresh: true,
9 }),
10 ],
11 server: {
12 cors: {
13 origin: [
14 // Supports: SCHEME://DOMAIN.laravel[:PORT]
15 /^https?:\/\/.*\.laravel(:\d+)?$/,
16 ],
17 },
18 },
19});

開発サーバURLの修正

Viteエコシステム内の一部のプラグインは、スラッシュで始まるURLは常にVite開発サーバを指すと想定しています。しかし、Laravel統合の性質上、そうではありません。

たとえば、vite-imagetoolsプラグインは、Viteがアセットを提供している間、次のようなURLを出力します。

1<img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

vite-imagetoolsプラグインは、出力URLがViteによってインターセプトされ、プラグインが/@imagetoolsで始まるすべてのURLを処理できることを期待しています。この動作を期待するプラグインを使用している場合は、URLを手動で修正する必要があります。これは、vite.config.jsファイルでtransformOnServeオプションを使用して行うことができます。

この特定の例では、生成されたコード内の/@imagetoolsのすべての出現箇所に開発サーバのURLを先頭に追加します。

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3import { imagetools } from 'vite-imagetools';
4 
5export default defineConfig({
6 plugins: [
7 laravel({
8 // ...
9 transformOnServe: (code, devServerUrl) => code.replaceAll('/@imagetools', devServerUrl+'/@imagetools'),
10 }),
11 imagetools(),
12 ],
13});

これで、Viteがアセットを提供している間、Vite開発サーバを指すURLが出力されるようになります。

1- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
2+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

Laravelは最も生産的な方法です
ソフトウェアを構築、デプロイ、監視します。