資產打包 (Vite)
- 簡介
- 安裝與設定
- 執行 Vite
- 使用 JavaScript
- 使用樣式表
- 使用 Blade 與路由
- 資產預取
- 自定義基礎 URL
- 環境變數
- 在測試中停用 Vite
- 伺服器端渲染 (SSR)
- Script 與 Style 標籤屬性
- 進階自定義
簡介
Vite 是一個現代的前端建構工具,它提供了極快的開發環境,並能將你的程式碼打包供正式環境使用。在使用 Laravel 構建應用程式時,你通常會使用 Vite 將應用程式的 CSS 和 JavaScript 檔案打包成正式環境就緒的資產。
Laravel 與 Vite 無縫整合,提供了官方外掛和 Blade 指令,以便在開發和正式環境中載入資產。
安裝與設定
[!NOTE] 以下文件討論如何手動安裝與設定 Laravel Vite 外掛。然而,Laravel 的入門套件 (Starter Kits) 已經包含了所有這些基本結構,是開始使用 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-react、@sveltejs/vite-plugin-svelte 或 @vitejs/plugin-vue。
Laravel Vite 外掛要求你指定應用程式的進入點 (Entry Points)。這些可以是 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 中執行開發伺服器
在 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 選項。
載入你的腳本與樣式
設定好 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>
{{-- 給定的建構路徑是相對於 public 路徑的。 --}}
@vite('resources/js/app.js', 'vendor/courier/build')
</head>
內嵌資產
有時可能有必要包含資產的原始內容,而不是連結到資產帶有版本號的 URL。例如,在將 HTML 內容傳遞給 PDF 產生器時,你可能需要直接在頁面中包含資產內容。你可以使用 Vite Facade 提供的 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。你可以透過 dev 指令執行開發伺服器,這在本地開發時非常有用。開發伺服器會自動偵測檔案的變更,並立即反映在任何開啟的瀏覽器視窗中。
或者,執行 build 指令會為應用程式資產標記版本並進行打包,供你部署到正式環境:
# 執行 Vite 開發伺服器...
npm run dev
# 為正式環境建構資產並標記版本...
npm run build
如果你是在 WSL2 上的 Sail 中執行開發伺服器,你可能需要一些額外的設定選項。
使用 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: {
// 當在單檔案組件 (SFC) 中引用時,Vue 外掛會重寫資產 URL,
// 以指向 Laravel 網頁伺服器。將此項設置為 `null` 允許
// Laravel 外掛改為將資產 URL 重寫為指向 Vite 伺服器。
base: null,
// Vue 外掛會解析絕對 URL 並將其視為磁碟上檔案的絕對路徑。
// 將此項設置為 `false` 將保持絕對 URL 不變,
// 這樣它們就可以按預期引用 public 目錄中的資產。
includeAbsolute: false,
},
},
}),
],
});
[!NOTE] Laravel 的入門套件 (Starter Kits) 已經包含了適當的 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 的入門套件 (Starter Kits) 已經包含了適當的 Laravel、React 和 Vite 設定。這些入門套件提供了開始使用 Laravel、React 和 Vite 最快的方式。
Svelte
如果你想使用 Svelte 框架建構前端,那麼你還需要安裝 @sveltejs/vite-plugin-svelte 外掛:
npm install --save-dev @sveltejs/vite-plugin-svelte
接著你可以在 vite.config.js 設定檔案中包含該外掛。
import { svelte } from ' @sveltejs/vite-plugin-svelte';
import laravel from 'laravel-vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.ts'],
ssr: 'resources/js/ssr.ts',
refresh: true,
}),
svelte(),
],
});
[!NOTE] Laravel 的入門套件 (Starter Kits) 已經包含了適當的 Laravel、Svelte 和 Vite 設定。這些入門套件提供了開始使用 Laravel、Svelte 和 Vite 最快的方式。
Inertia
Laravel Vite 外掛提供了一個方便的 resolvePageComponent 函式,以幫助你解析 Inertia 頁面組件。以下是在 Vue 3 中使用該輔助函式的範例;不過,你也可以在 React 或 Svelte 等其他框架中使用該函式:
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 的程式碼拆分 (Code Splitting) 功能,我們建議設定資產預取。
[!NOTE] Laravel 的入門套件 (Starter Kits) 已經包含了適當的 Laravel、Inertia 和 Vite 設定。這些入門套件提供了開始使用 Laravel、Inertia 和 Vite 最快的方式。
URL 處理
在使用 Vite 並在應用程式的 HTML、CSS 或 JS 中引用資產時,有幾點需要注意。首先,如果你使用絕對路徑引用資產,Vite 將不會在建構中包含該資產;因此,你應該確保資產在你的 public 目錄中可用。在使用專用的 CSS 進入點時,應避免使用絕對路徑,因為在開發過程中,瀏覽器會嘗試從託管 CSS 的 Vite 開發伺服器加載這些路徑,而不是從你的 public 目錄加載。
在引用相對資產路徑時,你應該記住路徑是相對於引用它們的檔案。任何透過相對路徑引用的資產都將被 Vite 重寫、標記版本並打包。
考慮以下專案結構:
public/
taylor.png
resources/
js/
Pages/
Welcome.vue
images/
abigail.png
以下範例展示了 Vite 如何處理相對和絕對 URL:
<!-- 此資產不被 Vite 處理,且不會包含在建構中 -->
<img src="/taylor.png">
<!-- 此資產將由 Vite 重寫、標記版本並打包 -->
<img src="../../images/abigail.png">
使用樣式表
[!NOTE] Laravel 的入門套件 (Starter Kits) 已經包含了適當的 Tailwind 和 Vite 設定。或者,如果你想在不使用入門套件的情況下使用 Tailwind 和 Laravel,請查看 Tailwind 的 Laravel 安裝指南。
所有的 Laravel 應用程式都已經包含了 Tailwind 和一個配置正確的 vite.config.js 檔案。因此,你只需要啟動 Vite 開發伺服器或執行 dev Composer 指令,這將同時啟動 Laravel 和 Vite 開發伺服器:
composer run dev
你應用程式的 CSS 可以放在 resources/css/app.css 檔案中。
使用 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 處理。接著你可以在 Blade 模板中使用 Vite::asset 方法來引用這些資產,該方法將回傳給定資產標記版本後的 URL:
<img src="{{ Vite::asset('resources/images/logo.png') }}">
儲存時自動重新整理
當你的應用程式是使用傳統的 Blade 伺服器端渲染建構時,Vite 可以透過在您更改應用程式中的視圖 (View) 檔案時自動重新整理瀏覽器來改進開發流程。要開始使用,只需將 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 }
}],
}),
],
});
別名
在 JavaScript 應用程式中,為經常引用的目錄建立別名是很常見的。但是,你也可以透過在 Illuminate\Support\Facades\Vite 類別上使用 macro 方法來建立供 Blade 使用的別名。通常,「macros」應該在服務提供者 (Service Provider) 的 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 的程式碼拆分 (Code Splitting) 功能建構 SPA 時,會在每次頁面導覽時獲取所需的資產。這種行為可能會導致 UI 渲染延遲。如果這對你選擇的前端框架來說是個問題,Laravel 提供了在初始頁面加載時主動預取應用程式 JavaScript 和 CSS 資產的能力。
你可以透過在服務提供者 (Service Provider) 的 boot 方法中呼叫 Vite::prefetch 方法來指示 Laravel 主動預取資產:
<?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 事件時,預取將會開始。例如,你可以讓預取在頁面加載後三秒開始:
<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 重寫,因此它們不會被加上前綴。
環境變數
你可以在應用程式的 .env 檔案中為環境變數加上 VITE_ 前綴,將其注入到 JavaScript 中:
VITE_SENTRY_DSN_PUBLIC=http://example.com
你可以透過 import.meta.env 物件存取注入的環境變數:
import.meta.env.VITE_SENTRY_DSN_PUBLIC
在測試中停用 Vite
Laravel 的 Vite 整合在執行測試時會嘗試解析你的資產,這需要你執行 Vite 開發伺服器或建構資產。
如果你希望在測試期間模擬 (Mock) Vite,可以呼叫 withoutVite 方法,該方法適用於任何擴充 Laravel TestCase 類別的測試:
```php tab=Pest test('without vite example', function () { $this->withoutVite();
// ...
});
```php tab=PHPUnit
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
如果你是將 SSR 與 Inertia 搭配使用,則可以使用 inertia:start-ssr Artisan 指令來啟動 SSR 伺服器:
php artisan inertia:start-ssr
[!NOTE] Laravel 的入門套件 (Starter Kits) 已經包含了適當的 Laravel、Inertia SSR 和 Vite 設定。這些入門套件提供了開始使用 Laravel、Inertia SSR 和 Vite 最快的方式。
Script 與 Style 標籤屬性
內容安全政策 (CSP) Nonce
如果你希望在 script 和 style 標籤中包含 nonce 屬性 作為 內容安全政策 (Content Security Policy) 的一部分,你可以在自定義 中介層 (Middleware) 中使用 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 將自動在所有產生的 script 和 style 標籤中包含 nonce 屬性。
如果你需要在其他地方指定 nonce,包括 Laravel 入門套件 中包含的 Ziggy @route 指令,你可以使用 cspNonce 方法獲取它:
@routes(nonce: Vite::cspNonce())
如果你已經有一個想要指示 Laravel 使用的 nonce,可以將該 nonce 傳遞給 useCspNonce 方法:
Vite::useCspNonce($nonce);
子資源完整性 (SRI)
如果你的 Vite manifest 包含資產的 integrity 雜湊值,Laravel 將自動在它產生的任何 script 和 style 標籤上加入 integrity 屬性,以執行 子資源完整性 (Subresource Integrity)。預設情況下,Vite 不會在它的 manifest 中包含 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]
],
});
如果需要,你也可以自定義可以在其中找到完整性雜湊值的 manifest 鍵名:
use Illuminate\Support\Facades\Vite;
Vite::useIntegrityKey('custom-integrity-key');
如果你想完全停用此自動偵測,可以向 useIntegrityKey 方法傳遞 false:
Vite::useIntegrityKey(false);
任意屬性
如果你需要在 script 和 style 標籤中包含額外的屬性,例如 data-turbo-track 屬性,你可以透過 useScriptTagAttributes 和 useStyleTagAttributes 方法指定它們。通常,這些方法應該在服務提供者 (Service Provider) 中呼叫:
use Illuminate\Support\Facades\Vite;
Vite::useScriptTagAttributes([
'data-turbo-track' => 'reload', // 指定屬性的值...
'async' => true, // 指定不帶值的屬性...
'integrity' => false, // 排除原本會包含的屬性...
]);
Vite::useStyleTagAttributes([
'data-turbo-track' => 'reload',
]);
如果你需要條件式地加入屬性,可以傳遞一個回呼函式,該函式將接收資產來源路徑、其 URL、其 manifest chunk 以及完整的 manifest:
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') // 自定義 manifest 檔案名稱...
->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', // 自定義 manifest 檔案名稱...
},
});
開發伺服器跨來源資源共用 (CORS)
如果在從 Vite 開發伺服器獲取資產時,在瀏覽器中遇到跨來源資源共用 (CORS) 問題,你可能需要授予你的自定義來源存取開發伺服器的權限。Vite 結合 Laravel 外掛允許以下來源,無需任何額外設定:
::1127.0.0.1localhost*.test*.localhost- 專案
.env中的APP_URL
為專案允許自定義來源最簡單的方法是確保應用程式的 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]
});
你也可以包含正則表達式 (Regex) 模式,如果你想允許給定頂級網域的所有來源(例如 *.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]
// 支援:SCHEME://DOMAIN.laravel[:PORT] [tl! add]
/^https?:\/\/.*\.laravel(:\d+)?$/, //[tl! add]
], // [tl! add]
}, // [tl! add]
}, // [tl! add]
});
修正開發伺服器 URL
Vite 生態系統中的某些外掛假設以正斜線開頭的 URL 始終指向 Vite 開發伺服器。然而,由於 Laravel 整合的性質,情況並非如此。
例如,當 Vite 提供資產服務時,vite-imagetools 外掛會輸出如下 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] -->
ClearcutLogger: Flush already in progress, marking pending flush.