Laravel 9.x アセットの構築(Vite)

イントロダクション

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

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

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

ViteとLaravel Mixの選択

Viteへ移行する前、新しいLaravelアプリケーションは、アセットをバンドルする際にwebpackで動作するMixを使用していました。Viteは、リッチなJavaScriptアプリケーションを構築する際に、より速く、より生産的な体験を提供することに重点を置いています。Inertia のようなツールで開発したものを含め、シングルページアプリケーション(SPA)を開発している場合、Viteは完璧にフィットするでしょう。

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

Mixへ戻す

Vite scaffoldingを使用して新しいLaravelアプリケーションを開始したが、Laravel Mixとwebpackへ戻る必要があるのですか?大丈夫です。ViteからMixへの移行に関する公式ガイドを参照してください。

インストールと準備

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

Nodeのインストール

ViteとLaravelプラグインを実行する前に、Node.js(16以上)とNPMを確実にインストールしてください。

node -v
npm -v

NodeとNPMの最新版は、Node公式サイトからグラフィカルインストーラを使って簡単にインストールできます。また、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',
        ]),
    ],
});

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

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

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

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

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

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

セキュアな開発サーバの取り扱い

Valetのセキュアコマンドを含め、開発用WebサーバがHTTPSで動作している場合、Vite開発サーバへの接続に問題が発生する可能性があります。Vite設定ファイルのvite.config.jsへ以下を追加すれば、ViteをHTTPSでも動作するように設定できます。

export default defineConfig({
    // ...
    server: { // [tl! 追加]
        https: true, // [tl! 追加]
        host: 'localhost', // [tl! 追加]
    }, // [tl! 追加]
});

また、npm run devコマンドを実行する際に、コンソールの「Local」リンクをたどり、ブラウザでViteの開発サーバの証明書の警告を受け入れる必要があります。

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

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開発サーバを自動的に検出し、Viteクライアントを注入してホットモジュール置換を有効にします。ビルドモードでは、このディレクティブはインポートしたCSSを含む、コンパイル済みのバージョン管理しているアセットを読み込みます。

Viteの実行

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

もしくは、buildコマンドを実行すると、アプリケーションのアセットをバージョン付けして構築し、本番環境にデプロイできる状態にします。

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

# 実働用にアセットをバンドルし、バージョン付けする
npm run build

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

LaravelプラグインでVueプラグインを使用する場合、vite.config.js設定ファイルへ追加オプションをいくつか追加する必要があります。

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プラグインは、Single File Componentsで
                    // 参照する場合、アセットの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

Viteを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/inertia-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 }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
});

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

URL処理

Viteを使用して、アプリケーションのHTML、CSS、JSアセットを参照する場合、いくつか考慮すべき点があります。まず、絶対パスでアセットを参照した場合、Viteはそのアセットをビルドに含めません。したがって、そのアセットがパブリックディレクトリで利用可能であることを確認する必要があります。

相対パスで参照する場合、参照するファイルからの相対パスであることを覚えておく必要があります。相対パスで参照されたアセットは、Viteによって書き直され、バージョン付けされ、バンドルされます。

以下のようなプロジェクト構成を考えてみましょう。

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

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

<!-- このアセットをViteは扱わず、バンドルへ含まれない -->
<img src="/taylor.png">

<!-- このアセットは書き換えられ、バージョン付けし、バンドルへ含まれる -->
<img src="../../images/abigail.png">

スタイルシートの操作

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

module.exports = {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    },
};

Bladeとルートの操作

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

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

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

refreshオプションがtrueの場合、resources/views/**app/View/Components/**routes/**のファイルを保存すると、npm run dev実行中に、ブラウザがページのフル再ロードを行うようになります。

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

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

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 }
            }],
        }),
    ],
});

ベース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で書き直されないため、プリフィックスが付かないことを覚えておいてください。

環境変数

アプリケーションの.envファイルに、VITE_ というプレフィックスを付ける環境変数を設置することで、それらの環境変数をJavaScriptへ注入できます。

VITE_SENTRY_DSN_PUBLIC=http://example.com

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

import.meta.env.VITE_SENTRY_DSN_PUBLIC

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

Laravel Viteプラグインを使用すると、Viteでサーバサイドレンダリングを簡単に設定できます。まず、SSRエントリーポイントをresources/js/ssr.jsに作成し、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! 削除]
     "build": "vite build && vite build --ssr" // [tl! 追加]
}

最後に、SSRサーバの構築と起動のため、以下のコマンドを実行してください。

npm run build
node bootstrap/ssr/ssr.mjs

Note: Laravelのスターターキットには、すでに適切なLaravel、Inertia SSR、Viteの構成が含まれています。Laravel、Inertia SSR、Viteを最速で使い始めるため、Laravel Breeze をチェックしてください。

Scriptとstyleタグ属性

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

コンテンツセキュリティポリシー](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)の一環として、スクリプトやスタイルタグに、nonce属性を含めたい場合は、カスタムミドルウェアuseCspNonceメソッドを使用して、ノンスを生成・指定できます。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Vite;

class AddContentSecurityPolicyHeaders
{
    /**
     * 受診リクエストの処理
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        Vite::useCspNonce();

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

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

Laravelのスターターキットに含まれるZiggy @route directiveなど、別の場所でノンスを指定する必要がある場合、cspNonceメソッドを使用して取得できます。

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

Laravelに使わせたいノンスが既にある場合は、useCspNonceメソッドへ、そのノンスを渡してください。

Vite::useCspNonce($nonce);

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

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

npm install -D 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);

任意の属性

もし、スクリプトタグやスタイルタグに追加の属性、例えば 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になります。

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる