LaravelDocs(中文)

資源打包 (Vite)

Laravel 與 Vite 的整合指南

簡介 (Introduction)

Vite 是一個現代化的前端建置工具,提供極快的開發環境並將你的程式碼打包用於生產環境。在使用 Laravel 建置應用程式時,你通常會使用 Vite 將應用程式的 CSS 和 JavaScript 檔案打包成生產環境可用的資源。

Laravel 透過提供官方外掛和 Blade 指令來載入你的開發和生產資源,與 Vite 無縫整合。

安裝 & Setup (Installation)

[!NOTE] 以下文件討論如何手動安裝和設定 Laravel Vite 外掛。但是,Laravel 的 啟動套件 已經包含了所有這些鷹架,是開始使用 Laravel 和 Vite 的最快方式。

Installing Node

You must ensure that Node.js (16+) and NPM are installed before running Vite and the Laravel plugin:

node -v
npm -v

你可以使用 Node 官方網站 的簡易圖形安裝程式輕鬆安裝最新版本的 Node 和 NPM。或者,如果你使用的是 Laravel Sail,你可以透過 Sail 呼叫 Node 和 NPM:

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

Installing Vite and the Laravel Plugin

在全新安裝的 Laravel 中,你會在應用程式目錄結構的根目錄中找到一個 package.json 檔案。預設的 package.json 檔案已經包含了開始使用 Vite 和 Laravel 外掛所需的一切。你可以透過 NPM 安裝應用程式的前端依賴項目:

npm install

Configuring 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 進入點

Working With a Secure Development Server

如果你的本機開發 Web 伺服器透過 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]
    }),
  ],
});

當使用其他 Web 伺服器時,你應該產生一個受信任的憑證並手動設定 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 開發伺服器的憑證警告。

Running the Development Server in Sail on WSL2

當在 Windows Subsystem for Linux 2 (WSL2) 上的 Laravel Sail 中執行 Vite 開發伺服器時,你應該在 vite.config.js 檔案中新增以下設定,以確保瀏覽器可以與開發伺服器通訊:

// ...

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

如果在開發伺服器執行時你的檔案變更沒有反映在瀏覽器中,你可能還需要設定 Vite 的 server.watch.usePolling 選項

Loading Your Scripts and Styles

設定好 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 客戶端以啟用熱模組替換 (Hot Module Replacement)。在建置模式下,該指令將載入你編譯和版本化的資源,包括任何匯入的 CSS。

如果需要,你也可以在呼叫 @vite 指令時指定編譯資源的建置路徑:

<!doctype html>
<head>
    {{-- Given build path is relative to public path. --}}

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

Inline Assets

有時可能需要包含資源的原始內容,而不是連結到資源的版本化 URL。例如,當將 HTML 內容傳遞給 PDF 產生器時,你可能需要將資源內容直接包含在頁面中。你可以使用 Vite facade 提供的 content 方法輸出 Vite 資源的內容:

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

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


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

Running Vite

你可以透過兩種方式執行 Vite。你可以透過 dev 指令執行開發伺服器,這在本地開發時非常有用。開發伺服器會自動偵測檔案的變更,並立即反映在任何開啟的瀏覽器視窗中。

或者,執行 build 指令將版本化並打包應用程式的資源,並準備好讓你部署到生產環境:

# Run the Vite development server...
npm run dev

# Build and version the assets for production...
npm run build

如果你在 WSL2 上的 Sail 中執行開發伺服器,你可能需要一些 額外的設定 選項。

Working With JavaScript

Aliases

預設情況下,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: {
          // The Vue plugin will re-write asset URLs, when referenced
          // in Single File Components, to point to the Laravel web
          // server. Setting this to `null` allows the Laravel plugin
          // to instead re-write asset URLs to point to the Vite
          // server instead.
          base: null,

          // The Vue plugin will parse absolute URLs and treat them
          // as absolute paths to files on disk. Setting this to
          // `false` will leave absolute URLs un-touched so they can
          // reference assets in the public directory as expected.
          includeAbsolute: false,
        },
      },
    }),
  ],
});

[!NOTE] Laravel 的 啟動套件 已經包含了正確的 Laravel、Vue 和 Vite 設定。這些啟動套件是開始使用 Laravel、Vue 和 Vite 的最快方式。

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 的最快方式。

Inertia

Laravel Vite 外掛提供了一個方便的 resolvePageComponent 函式來幫助你解析 Inertia 頁面組件。以下是該輔助函式與 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 }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el);
  },
});

如果你在 Inertia 中使用 Vite 的程式碼分割功能,我們建議設定 資源預先取得 (Asset Prefetching)

[!NOTE] Laravel 的 啟動套件 已經包含了正確的 Laravel、Inertia 和 Vite 設定。這些啟動套件是開始使用 Laravel、Inertia 和 Vite 的最快方式。

URL Processing

當使用 Vite 並在應用程式的 HTML、CSS 或 JS 中參考資源時,有幾個注意事項需要考慮。首先,如果你使用絕對路徑參考資源,Vite 不會將資源包含在建置中;因此,你應該確保資源在你的 public 目錄中可用。你應該避免在使用 專用 CSS 進入點 時使用絕對路徑,因為在開發過程中,瀏覽器會嘗試從託管 CSS 的 Vite 開發伺服器載入這些路徑,而不是從你的 public 目錄。

當參考相對資源路徑時,你應該記住路徑是相對於參考它們的檔案的。任何透過相對路徑參考的資源都將被 Vite 重寫、版本化和打包。

考慮以下專案結構:

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

以下範例示範了 Vite 如何處理相對和絕對 URL:

<!-- This asset is not handled by Vite and will not be included in the build -->
<img src="/taylor.png" />

<!-- This asset will be re-written, versioned, and bundled by Vite -->
<img src="../../images/abigail.png" />

Working With Stylesheets

[!NOTE] Laravel 的 啟動套件 已經包含了正確的 Tailwind 和 Vite 設定。或者,如果你想在不使用我們的啟動套件的情況下使用 Tailwind 和 Laravel,請查看 Tailwind 的 Laravel 安裝指南

所有 Laravel 應用程式都已經包含 Tailwind 和設定正確的 vite.config.js 檔案。因此,你只需要啟動 Vite 開發伺服器或執行 dev Composer 指令,這將同時啟動 Laravel 和 Vite 開發伺服器:

composer run dev

你的應用程式 CSS 可以放在 resources/css/app.css 檔案中。

Working With Blade and Routes

Processing Static Assets With 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') }}" />

Refreshing on Save

當你的應用程式使用 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/**

如果你使用 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 },
        },
      ],
    }),
  ],
});

Aliases

在 JavaScript 應用程式中,為經常參考的目錄 建立別名 是很常見的。但是,你也可以透過在 Illuminate\Support\Facades\Vite 類別上使用 macro 方法來建立在 Blade 中使用的別名。通常,「巨集」應該在 服務提供者boot 方法中定義:

/**
 * Bootstrap any application services.
 */
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" />

Asset Prefetching

當使用 Vite 的程式碼分割功能建置 SPA 時,所需的資源會在每次頁面導覽時取得。這種行為可能會導致 UI 渲染延遲。如果這對你選擇的前端框架造成問題,Laravel 提供了在初始頁面載入時預先取得應用程式 JavaScript 和 CSS 資源的能力。

你可以透過在 服務提供者boot 方法中呼叫 Vite::prefetch 方法來指示 Laravel 預先取得你的資源:

<?php

namespace App\Providers;

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

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Vite::prefetch(concurrency: 3);
    }
}

在上面的範例中,資源將在每次頁面載入時以最多 3 個並發下載進行預先取得。你可以修改並發數以符合應用程式的需求,或者如果應用程式應該一次下載所有資源,則不指定並發限制:

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Vite::prefetch();
}

預設情況下,預先取得將在 頁面 load 事件 觸發時開始。如果你想自訂預先取得開始的時間,你可以指定 Vite 將監聽的事件:

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Vite::prefetch(event: 'vite:prefetch');
}

鑑於上面的程式碼,預先取得現在將在你手動在 window 物件上調度 vite:prefetch 事件時開始。例如,你可以讓預先取得在頁面載入三秒後開始:

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

Custom Base URLs

如果你的 Vite 編譯資源部署到與應用程式分開的網域(例如透過 CDN),你必須在應用程式的 .env 檔案中指定 ASSET_URL 環境變數:

ASSET_URL=https://cdn.example.com

設定資源 URL 後,所有重寫的資源 URL 都將以設定的值為前綴:

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

請記住,絕對 URL 不會被 Vite 重寫,因此它們不會被加上前綴。

Environment Variables

你可以透過在應用程式的 .env 檔案中為環境變數加上 VITE_ 前綴,將它們注入到你的 JavaScript 中:

VITE_SENTRY_DSN_PUBLIC=http://example.com

你可以透過 import.meta.env 物件存取注入的環境變數:

import.meta.env.VITE_SENTRY_DSN_PUBLIC;

Disabling Vite in Tests

Laravel 的 Vite 整合將嘗試在執行測試時解析你的資源,這要求你執行 Vite 開發伺服器或建置你的資源。

如果你希望在測試期間模擬 Vite,你可以呼叫 withoutVite 方法,該方法可用於任何繼承 Laravel TestCase 類別的測試:

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]
}

Server-Side Rendering (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 的最快方式。

Script and Style Tag Attributes

Content Security Policy (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
{
    /**
     * Handle an incoming request.
     *
     * @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 屬性。

如果你需要在其他地方指定 nonce,包括 Laravel 啟動套件 中包含的 Ziggy @route 指令,你可以使用 cspNonce 方法檢索它:

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

如果你已經有一個想要指示 Laravel 使用的 nonce,你可以將 nonce 傳遞給 useCspNonce 方法:

Vite::useCspNonce($nonce);

Subresource Integrity (SRI)

如果你的 Vite 清單包含資源的 integrity 雜湊,Laravel 將自動將 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');

如果你想完全停用此自動偵測,你可以將 false 傳遞給 useIntegrityKey 方法:

Vite::useIntegrityKey(false);

Arbitrary Attributes

如果你需要在腳本和樣式標籤上包含其他屬性,例如 data-turbo-track 屬性,你可以透過 useScriptTagAttributesuseStyleTagAttributes 方法指定它們。通常,此方法應從 服務提供者 呼叫:

use Illuminate\Support\Facades\Vite;

Vite::useScriptTagAttributes([
    'data-turbo-track' => 'reload', // Specify a value for the attribute...
    'async' => true, // Specify an attribute without a value...
    'integrity' => false, // Exclude an attribute that would otherwise be included...
]);

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

Advanced Customization

開箱即用,Laravel 的 Vite 外掛使用合理的慣例,這應該適用於大多數應用程式;但是,有時你可能需要自訂 Vite 的行為。為了啟用其他自訂選項,我們提供以下方法和選項,可用於代替 @vite Blade 指令:

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

    {{
        Vite::useHotFile(storage_path('vite.hot')) // Customize the "hot" file...
            ->useBuildDirectory('bundle') // Customize the build directory...
            ->useManifestFilename('assets.json') // Customize the manifest filename...
            ->withEntryPoints(['resources/js/app.js']) // Specify the entry points...
            ->createAssetPathsUsing(function (string $path, ?bool $secure) { // Customize the backend path generation for built assets...
                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", // Customize the "hot" file...
      buildDirectory: "bundle", // Customize the build directory...
      input: ["resources/js/app.js"], // Specify the entry points...
    }),
  ],
  build: {
    manifest: "assets.json", // Customize the manifest filename...
  },
});

Dev Server Cross-Origin Resource Sharing (CORS)

如果你在瀏覽器中從 Vite 開發伺服器取得資源時遇到跨來源資源共享 (CORS) 問題,你可能需要允許你的自訂來源存取開發伺服器。Vite 結合 Laravel 外掛允許以下來源,無需任何額外設定:

  • ::1
  • 127.0.0.1
  • localhost
  • *.test
  • *.localhost
  • APP_URL in the project's .env

允許專案使用自訂來源的最簡單方法是確保應用程式的 APP_URL 環境變數與你在瀏覽器中存取的來源相符。例如,如果你存取 https://my-app.laravel,你應該更新你的 .env 以符合:

APP_URL=https://my-app.laravel

如果你需要對來源進行更精細的控制,例如支援多個來源,你應該利用 Vite 全面且靈活的內建 CORS 伺服器設定。例如,你可以在專案的 vite.config.js 檔案中的 server.cors.origin 設定選項中指定多個來源:

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

export default defineConfig({
  plugins: [
    laravel({
      input: "resources/js/app.js",
      refresh: true,
    }),
  ],
  server: {
    // [tl! add]
    cors: {
      // [tl! add]
      origin: [
        // [tl! add]
        "https://backend.laravel", // [tl! add]
        "http://admin.laravel:8566", // [tl! add]
      ], // [tl! add]
    }, // [tl! add]
  }, // [tl! add]
});

你也可以包含正規表達式模式,如果你想允許給定頂級網域的所有來源(例如 *.laravel),這會很有幫助:

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

export default defineConfig({
  plugins: [
    laravel({
      input: "resources/js/app.js",
      refresh: true,
    }),
  ],
  server: {
    // [tl! add]
    cors: {
      // [tl! add]
      origin: [
        // [tl! add]
        // Supports: SCHEME://DOMAIN.laravel[:PORT] [tl! add]
        /^https?:\/\/.*\.laravel(:\d+)?$/, //[tl! add]
      ], // [tl! add]
    }, // [tl! add]
  }, // [tl! add]
});

Correcting Dev Server URLs

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] -->