> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 以 Vite 進行 asset bundling

> 說明如何在 Laravel 專案中用 Vite 打包 JavaScript／CSS，並以熱重載建構舒適的開發環境。

## 什麼是 Laravel 與 Vite

[Vite](https://vitejs.dev) 是高速的前端建置工具。開發時提供即時反映檔案變更的 Hot Module Replacement（HMR），正式環境建置時產生最佳化的 asset。

Laravel 9 起，Vite 被採用為標準前端建置工具，並透過 `laravel-vite-plugin` 與 Laravel 整合。此外掛的主要職責如下：

* 管理進入點（entry point）
* 支援開發伺服器 HMR
* 與 `@vite()` Blade 指示詞整合
* 正式建置時的 asset 版本化（cache busting）

<Info>
  使用 Laravel 起始套件（如 Laravel Breeze）時，Vite 與 Tailwind 設定已包含。本頁說明從零設定的方法。
</Info>

<Tip>
  Vite 在 Laravel 整體前端結構中的定位，可先在 [前端](/zh-TW/frontend) 確認全景。
</Tip>

## 安裝與設定

### 確認 Node 已安裝

使用 Vite 需要 Node.js（16 以上）與 npm。確認是否已安裝。

```shell theme={null}
node -v
npm -v
```

### 安裝套件

新裝的 Laravel 專案 `package.json` 已包含 `vite` 與 `laravel-vite-plugin`。以下列指令安裝相依：

```shell theme={null}
npm install
```

### vite.config.js 設定

專案根目錄已產生 `vite.config.js`。可指定進入點（bundle 起點檔案）。

```js theme={null}
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

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

<Tip>
  若使用 SPA 或 Inertia，建議以 JavaScript import CSS 的形式。此時可將 `resources/css/app.css` 從進入點移除，於 `resources/js/app.js` 開頭加上 `import '../css/app.css';`。
</Tip>

## 啟動開發伺服器

開發時以 `npm run dev` 啟動 Vite 開發伺服器。變更檔案時瀏覽器會自動更新（HMR）。

```shell theme={null}
npm run dev
```

也可與 Laravel 開發伺服器同時啟動：

```shell theme={null}
composer run dev
```

<Info>
  `composer run dev` 會同時啟動 `php artisan serve` 與 `npm run dev`。
</Info>

### Blade view 的自動 reload

設定 `refresh: true` 後，儲存 Blade view 或路由檔案時瀏覽器會自動 reload。

```js theme={null}
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

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

`refresh: true` 時，以下目錄的變更會被監控：

* `resources/views/**`
* `app/Livewire/**`
* `routes/**`
* `lang/**`

## 正式建置

在部署到正式環境前執行 `npm run build`。asset 會被打包並版本化，輸出到 `public/build/`。

```shell theme={null}
npm run build
```

建置後的目錄結構範例：

```text theme={null}
public/
  build/
    assets/
      app-Cv82Mlke.css
      app-DnAZBF4U.js
    manifest.json
```

`manifest.json` 記錄檔名與 hash 的對應，`@vite()` 指示詞會參考此檔載入正確檔案。

<Warning>
  `public/build/` 目錄是建置產物，建議加入 `.gitignore`。可在部署目的地執行建置，或在 CI 建置後部署。
</Warning>

## 從 Blade 載入 asset

在版面的 `<head>` 加入 `@vite()` Blade 指示詞。

```blade theme={null}
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ config('app.name') }}</title>

    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    @yield('content')
</body>
</html>
```

若從 JavaScript import CSS，只指定 JavaScript 進入點即可。

```blade theme={null}
@vite('resources/js/app.js')
```

`@vite()` 指示詞會依開發或正式環境自動切換行為。

| 情境       | 行為                                       |
| -------- | ---------------------------------------- |
| 開發伺服器運行中 | 從 Vite 開發伺服器載入 asset，並啟用 HMR             |
| 正式（已建置）  | 參考 `public/build/manifest.json` 載入帶版本的檔案 |

## JavaScript／CSS 進入點設定

### JavaScript 的設定

`resources/js/app.js` 為主要進入點。從此 import 其他模組。

```js theme={null}
import './bootstrap';
import '../css/app.css';

// import 自訂模組
import './components/modal';
import './utils/format';
```

### CSS 的設定

於 `resources/css/app.css` 撰寫全域樣式。

```css theme={null}
/* 使用 Tailwind CSS 時 */
@import 'tailwindcss';

/* 自訂樣式 */
body {
    font-family: 'Noto Sans TC', sans-serif;
}
```

### 多個進入點

如管理畫面等要在不同頁面打包不同 asset 時，可指定多個進入點。

```js theme={null}
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

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

在 Blade 只載入對應的進入點：

```blade theme={null}
{{-- 管理畫面版面 --}}
@vite(['resources/css/admin.css', 'resources/js/admin.js'])
```

## 與 Tailwind CSS 整合

Tailwind CSS v4 以後可作為 Vite 外掛整合。

<Steps>
  <Step title="安裝 Tailwind">
    ```shell theme={null}
    npm install tailwindcss @tailwindcss/vite
    ```
  </Step>

  <Step title="在 vite.config.js 加入外掛">
    ```js theme={null}
    import { defineConfig } from 'vite';
    import laravel from 'laravel-vite-plugin';
    import tailwindcss from '@tailwindcss/vite';

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

  <Step title="在 CSS 匯入 Tailwind">
    ```css theme={null}
    /* resources/css/app.css */
    @import 'tailwindcss';
    ```
  </Step>
</Steps>

<Info>
  使用 Tailwind CSS v3 時需要 `tailwind.config.js` 與 `postcss.config.js`。最新的 Tailwind CSS v4 不需要這些檔案。
</Info>

## Alias 設定

`laravel-vite-plugin` 會自動設定 `@` alias，指向 `resources/js` 目錄。

```js theme={null}
// 以 alias 進行 import
import UserCard from '@/components/UserCard.vue';
// 與下列等效
import UserCard from '/resources/js/components/UserCard.vue';
```

若要新增自訂 alias，在 `resolve.alias` 設定。

```js theme={null}
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import path from 'path';

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

使用 alias 的 import 範例：

```js theme={null}
import logo from '@images/logo.png';
import '@css/custom.css';
```

## 依框架的設定

### Vue

```shell theme={null}
npm install --save-dev @vitejs/plugin-vue
```

```js theme={null}
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: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
});
```

### React

```shell theme={null}
npm install --save-dev @vitejs/plugin-react
```

```js theme={null}
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(),
    ],
});
```

使用 React 時，於 Blade 樣板將 `@viteReactRefresh` 指示詞加在 `@vite` 之前。

```blade theme={null}
@viteReactRefresh
@vite('resources/js/app.jsx')
```

## 靜態 Asset 的處理

從 Blade 樣板參照的圖片或字型也可用 Vite 版本化。以 `assets` 選項指定對象目錄。

```js theme={null}
laravel({
    input: 'resources/js/app.js',
    assets: ['resources/images/**', 'resources/fonts/**'],
})
```

在 Blade 樣板中以 `Vite::asset()` 方法取得帶版本的 URL。

```blade theme={null}
<img src="{{ Vite::asset('resources/images/logo.png') }}" alt="Logo">
```

## 總結

| 需求                      | 方法                                                        |
| ----------------------- | --------------------------------------------------------- |
| 啟動開發伺服器                 | `npm run dev`                                             |
| 建置正式用 asset             | `npm run build`                                           |
| 於 Blade 載入 asset        | `@vite(['resources/css/app.css', 'resources/js/app.js'])` |
| Blade view 變更時自動 reload | 於 `vite.config.js` 設定 `refresh: true`                     |
| 使用 Tailwind CSS         | 加入 `@tailwindcss/vite` 外掛                                 |
| 使用 `@` alias            | 預設指向 `resources/js`                                       |
| 靜態 asset 版本化            | 使用 `assets` 選項與 `Vite::asset()`                           |

## 後續步驟

<Card title="快取" href="/zh-TW/cache" icon="database">
  學習 Laravel 快取功能，進一步提升應用效能。
</Card>


## Related topics

- [使用 Pest 進行進階測試](/zh-TW/advanced/testing-pest.md)
- [Laravel LSP — 以 Language Server Protocol 擴充 IDE 功能](/zh-TW/blog/laravel-lsp-introduction.md)
- [以 Orchestra Testbench 測試 Laravel 套件](/zh-TW/advanced/package-testing.md)
- [前端](/zh-TW/frontend.md)
- [速率限制的自訂](/zh-TW/advanced/rate-limiting.md)
