Skip to content

アセットバンドリング (Vite)

はじめに

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

Laravelは、公式プラグインとBladeディレクティブを提供することで、Viteとシームレスに統合されています。これにより、開発と本番の両方でアセットを読み込むことができます。

Note

Laravel Mixを使用していますか?新しいLaravelインストールでは、ViteがLaravel Mixに代わっています。Mixのドキュメントについては、Laravel Mixのウェブサイトをご覧ください。Viteに切り替えたい場合は、移行ガイドを参照してください。

ViteとLaravel Mixの選択

Viteに移行する前は、新しいLaravelアプリケーションはアセットをバンドルする際にMixを使用していました。これはwebpackをベースにしています。Viteは、リッチなJavaScriptアプリケーションを構築する際に、より高速で生産的な体験を提供することに焦点を当てています。Inertiaのようなツールを使用して開発されたものを含む、シングルページアプリケーション(SPA)を開発する場合、Viteは完璧に適合します。

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

Mixに戻す

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

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

Note

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

Nodeのインストール

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

node -v
npm -v

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

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

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

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

npm install

Viteの設定

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

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
});

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css', // [tl! remove]
            'resources/js/app.js',
        ]),
    ],
});

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

import './bootstrap';
import '../css/app.css'; // [tl! add]

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

セキュアな開発サーバーの操作

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

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

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            // ...
            detectTls: 'my-app.test', // [tl! add]
        }),
    ],
});

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

// ...
import fs from 'fs'; // [tl! add]

const host = 'my-app.test'; // [tl! add]

export default defineConfig({
    // ...
    server: { // [tl! add]
        host, // [tl! add]
        hmr: { host }, // [tl! add]
        https: { // [tl! add]
            key: fs.readFileSync(`/path/to/${host}.key`), // [tl! add]
            cert: fs.readFileSync(`/path/to/${host}.crt`), // [tl! add]
        }, // [tl! add]
    }, // [tl! add]
});

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

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

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

// ...

export default defineConfig({
    // ...
    server: { // [tl! add:start]
        hmr: {
            host: 'localhost',
        },
    }, // [tl! add:end]
});

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

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

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

<!DOCTYPE html>
<head>
    {{-- ... --}}

    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

JavaScriptを介してCSSをインポートしている場合は、JavaScriptエントリポイントのみを含める必要があります。

<!DOCTYPE html>
<head>
    {{-- ... --}}

    @vite('resources/js/app.js')
</head>

@viteディレクティブは、Vite開発サーバーを自動検出し、Hot Module Replacementを有効にするためにViteクライアントを注入します。ビルドモードでは、コンパイルされたバージョン付きアセットを読み込みます。

必要に応じて、@viteディレクティブを呼び出す際にコンパイルされたアセットのビルドパスを指定できます。

<!doctype html>
<head>
    {{-- 指定されたビルドパスは公開パスに対する相対パスです。 --}}

    @vite('resources/js/app.js', 'vendor/courier/build')
</head>

インラインアセット

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

@use('Illuminate\Support\Facades\Vite')

<!doctype html>
<head>
    {{-- ... --}}

    <style>
        {!! Vite::content('resources/css/app.css') !!}
    </style>
    <script>
        {!! Vite::content('resources/js/app.js') !!}
    </script>
</head>

Viteの実行

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

または、buildコマンドを実行すると、アプリケーションのアセットをバージョン管理し、バンドルして、本番環境にデプロイする準備を整えます:

# Vite開発サーバーを実行する...
npm run dev

# 本番用にアセットをビルドしてバージョン管理する...
npm run build

SailをWSL2で開発サーバーとして実行している場合、追加の設定が必要になるかもしれません。

JavaScriptの操作

エイリアス

デフォルトでは、Laravelプラグインは一般的なエイリアスを提供し、アプリケーションのアセットを便利にインポートできるようにします:

{
    '@' => '/resources/js'
}

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel(['resources/ts/app.tsx']),
    ],
    resolve: {
        alias: {
            '@': '/resources/ts',
        },
    },
});

Vue

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

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

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

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

export default defineConfig({
    plugins: [
        laravel(['resources/js/app.js']),
        vue({
            template: {
                transformAssetUrls: {
                    // Vueプラグインは、シングルファイルコンポーネント内で参照されるアセットURLを
                    // LaravelのWebサーバーを指すように書き換えます。これを`null`に設定すると、
                    // Laravelプラグインが代わりにアセットURLをViteサーバーを指すように書き換えます。
                    base: null,

                    // Vueプラグインは絶対URLを解析し、ディスク上のファイルへの絶対パスとして扱います。
                    // これを`false`に設定すると、絶対URLはそのままになり、期待通りに
                    // 公開ディレクトリ内のアセットを参照できます。
                    includeAbsolute: false,
                },
            },
        }),
    ],
});

Note

Laravelのスターターキットには、すでに適切なLaravel、Vue、Viteの設定が含まれています。Laravel、Vue、Viteでの開発を最速で始めるには、Laravel Breezeをチェックしてください。

React

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

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

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

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

export default defineConfig({
    plugins: [
        laravel(['resources/js/app.jsx']),
        react(),
    ],
});

JSXを含むファイルは、.jsxまたは.tsx拡張子を持つ必要があり、必要に応じてエントリーポイントを更新することを忘れないでください(上記のように)。

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

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

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

Note

Laravelのスターターキットには、すでに適切なLaravel、React、Viteの設定が含まれています。Laravel、React、Viteでの開発を最速で始めるには、Laravel Breezeをチェックしてください。

Inertia

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

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

createInertiaApp({
  resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
  setup({ el, App, props, plugin }) {
    return createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
});

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

Note

Laravelのスターターキットには、すでに適切なLaravel、Inertia、Viteの設定が含まれています。Laravel、Inertia、Viteでの開発を最速で始めるには、Laravel Breezeをチェックしてください。

URLの処理

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

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

以下のプロジェクト構造を考えてみましょう:

public/
  taylor.png
resources/
  js/
    Pages/
      Welcome.vue
  images/
    abigail.png

以下の例は、Viteが相対パスと絶対パスをどのように扱うかを示しています:

<!-- このアセットはViteによって処理されず、ビルドに含まれません -->
<img src="/taylor.png">

<!-- このアセットはViteによって書き換え、バージョン管理、およびバンドルされます -->
<img src="../../images/abigail.png">

スタイルシートの操作

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

export default {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    },
};

Note

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エントリーポイントに以下を追加する必要があります:

import.meta.glob([
  '../images/**',
  '../fonts/**',
]);

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

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

保存時のリフレッシュ

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            // ...
            refresh: true,
        }),
    ],
});

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

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

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

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            // ...
            refresh: ['resources/views/**'],
        }),
    ],
});

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            // ...
            refresh: [{
                paths: ['path/to/watch/**'],
                config: { delay: 300 }
            }],
        }),
    ],
});

エイリアス

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

/**
 * 任意のアプリケーションサービスをブートストラップします。
 */
public function boot(): void
{
    Vite::macro('image', fn (string $asset) => $this->asset("resources/images/{$asset}"));
}

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

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

アセットのプリフェッチ

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

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

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 任意のアプリケーションサービスを登録します。
     */
    public function register(): void
    {
        // ...
    }

    /**
     * 任意のアプリケーションサービスをブートストラップします。
     */
    public function boot(): void
    {
        Vite::prefetch(concurrency: 3);
    }
}

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

/**
 * 任意のアプリケーションサービスをブートストラップします。
 */
public function boot(): void
{
    Vite::prefetch();
}

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

/**
 * 任意のアプリケーションサービスをブートストラップします。
 */
public function boot(): void
{
    Vite::prefetch(event: 'vite:prefetch');
}

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

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

カスタムベースURL

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

ASSET_URL=https://cdn.example.com

アセットURLを設定した後、すべてのアセットのURLが設定された値でプレフィックスされます。

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

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

環境変数

アプリケーションの.envファイル内でVITE_をプレフィックスにして環境変数を注入することができます。

VITE_SENTRY_DSN_PUBLIC=http://example.com

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

import.meta.env.VITE_SENTRY_DSN_PUBLIC

テストでのViteの無効化

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

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

test('without vite example', function () {
    $this->withoutVite();

    // ...
});
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_without_vite_example(): void
    {
        $this->withoutVite();

        // ...
    }
}

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

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void// [tl! add:start]
    {
        parent::setUp();

        $this->withoutVite();
    }// [tl! add:end]
}

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

Laravel Viteプラグインを使用すると、Viteでサーバーサイドレンダリングを設定するのが簡単になります。開始するには、resources/js/ssr.jsにSSRエントリーポイントを作成し、Laravelプラグインに設定オプションを渡してエントリーポイントを指定します。

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            ssr: 'resources/js/ssr.js',
        }),
    ],
});

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

"scripts": {
     "dev": "vite",
     "build": "vite build" // [tl! remove]
     "build": "vite build && vite build --ssr" // [tl! add]
}

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

npm run build
node bootstrap/ssr/ssr.js

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

php artisan inertia:start-ssr

Note

Laravelのスターターキットには、すでに適切なLaravel、Inertia SSR、およびViteの設定が含まれています。Laravel、Inertia SSR、およびViteを最速で始めるには、Laravel Breezeをチェックしてください。

スクリプトとスタイルタグの属性

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

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

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Vite;
use Symfony\Component\HttpFoundation\Response;

class AddContentSecurityPolicyHeaders
{
    /**
     * 受信リクエストを処理します。
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        Vite::useCspNonce();

        return $next($request)->withHeaders([
            'Content-Security-Policy' => "script-src 'nonce-".Vite::cspNonce()."'",
        ]);
    }
}

useCspNonceメソッドを呼び出した後、Laravelは自動的にすべての生成されたスクリプトとスタイルタグにnonce属性を含めます。

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

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

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

Vite::useCspNonce($nonce);

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

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

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

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import manifestSRI from 'vite-plugin-manifest-sri';// [tl! add]

export default defineConfig({
    plugins: [
        laravel({
            // ...
        }),
        manifestSRI(),// [tl! add]
    ],
});

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

use Illuminate\Support\Facades\Vite;

Vite::useIntegrityKey('custom-integrity-key');

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

Vite::useIntegrityKey(false);

任意の属性

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

use Illuminate\Support\Facades\Vite;

Vite::useScriptTagAttributes([
    'data-turbo-track' => 'reload', // 属性の値を指定...
    'async' => true, // 値なしの属性を指定...
    'integrity' => false, // 通常は含まれる属性を除外...
]);

Vite::useStyleTagAttributes([
    'data-turbo-track' => 'reload',
]);

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

use Illuminate\Support\Facades\Vite;

Vite::useScriptTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
    'data-turbo-track' => $src === 'resources/js/app.js' ? 'reload' : false,
]);

Vite::useStyleTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
    'data-turbo-track' => $chunk && $chunk['isEntry'] ? 'reload' : false,
]);

Warning

Vite開発サーバーが実行されている間、$chunk$manifest引数はnullになります。

高度なカスタマイズ

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

<!doctype html>
<head>
    {{-- ... --}}

    {{
        Vite::useHotFile(storage_path('vite.hot')) // "hot"ファイルをカスタマイズ...
            ->useBuildDirectory('bundle') // ビルドディレクトリをカスタマイズ...
            ->useManifestFilename('assets.json') // マニフェストファイル名をカスタマイズ...
            ->withEntryPoints(['resources/js/app.js']) // エントリーポイントを指定...
            ->createAssetPathsUsing(function (string $path, ?bool $secure) { // ビルドされたアセットのバックエンドパス生成をカスタマイズ...
                return "https://cdn.example.com/{$path}";
            })
    }}
</head>

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            hotFile: 'storage/vite.hot', // "hot"ファイルをカスタマイズ...
            buildDirectory: 'bundle', // ビルドディレクトリをカスタマイズ...
            input: ['resources/js/app.js'], // エントリーポイントを指定...
        }),
    ],
    build: {
      manifest: 'assets.json', // マニフェストファイル名をカスタマイズ...
    },
});

開発サーバーURLの修正

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

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

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

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

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

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import { imagetools } from 'vite-imagetools';

export default defineConfig({
    plugins: [
        laravel({
            // ...
            transformOnServe: (code, devServerUrl) => code.replaceAll('/@imagetools', devServerUrl+'/@imagetools'),
        }),
        imagetools(),
    ],
});

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

- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520"><!-- [tl! remove] -->
+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520"><!-- [tl! add] -->

ユーザーノート