Vite 完全指南

Vite 是新世代的前端建構工具,提供極速的開發伺服器和優化的建構輸出。


目錄


什麼是 Vite?

Vite(法語意為「快速」)是由 Vue.js 作者尤雨溪開發的前端建構工具。

核心理念

  • 極速的冷啟動:使用原生 ES modules,無需打包
  • 🔥 即時熱更新(HMR):毫秒級的模組熱替換
  • 🎯 按需編譯:只編譯當前使用的模組
  • 📦 優化建構:使用 Rollup 進行生產打包

為什麼需要 Vite?

傳統建構工具(如 Webpack)的問題:

開發模式:
原始碼 → 打包整個應用 → 啟動伺服器
         ^^^^^^^^^^^^
         這一步很慢!(大專案可能需要數分鐘)

Vite 的解決方案:

開發模式:
原始碼 → 直接啟動伺服器 → 按需編譯模組
         ^^^^^^^^^^^^^
         幾乎瞬間啟動!

核心特性

1. 原生 ES Modules

開發時不打包,瀏覽器直接載入 ES modules:

// 瀏覽器直接理解這種語法
import { createApp } from 'vue'
import App from './App.vue'

2. 預建構依賴(Pre-bundling)

使用 esbuild 預建構 node_modules 依賴:

# 首次啟動時自動執行
Vite 發現 node_modules → esbuild 預建構 → 快取
                         ^^^^^^^^^^^^^^^^
                         用 Go 寫的,超快!

3. 即時 HMR(Hot Module Replacement)

// 修改程式碼後,只更新變更的模組
if (import.meta.hot) {
  import.meta.hot.accept((newModule) => {
    // 模組更新邏輯
  })
}

4. 生產優化

使用 Rollup 打包,自動進行:

  • Tree-shaking(移除未使用的程式碼)
  • 程式碼分割(Code splitting)
  • CSS 提取和壓縮
  • 資源優化

快速開始

建立新專案

# 使用 npm
npm create vite@latest my-app

# 使用 yarn
yarn create vite my-app

# 使用 pnpm
pnpm create vite my-app

選擇框架

? Select a framework:
  ❯ Vanilla        # 純 JavaScript
    Vue            # Vue 3
    React          # React
    Preact         # Preact
    Lit            # Lit
    Svelte         # Svelte
    Solid          # Solid
    Qwik           # Qwik
    Others

選擇變體

? Select a variant:
  ❯ TypeScript         # 使用 TypeScript
    JavaScript         # 使用 JavaScript
    TypeScript + SWC   # 使用 SWC 編譯器(更快)

啟動專案

cd my-app
npm install      # 安裝依賴
npm run dev      # 啟動開發伺服器

專案結構

典型的 Vite 專案結構

my-vite-app/
├── index.html              # 入口 HTML(在根目錄!)
├── package.json           # npm 依賴
├── vite.config.js         # Vite 配置檔案
├── public/                # 靜態資源(不經處理)
│   └── favicon.ico
└── src/                   # 原始碼
    ├── main.js            # JavaScript 入口
    ├── App.vue            # 主元件
    ├── components/        # 元件
    ├── assets/            # 資源檔案(會被處理)
    │   └── logo.png
    └── styles/            # 樣式檔案
        └── main.css

關鍵差異:index.html 在根目錄

Webpack:

public/index.html  ← HTML 在 public 目錄
src/main.js

Vite:

index.html         ← HTML 在根目錄!
src/main.js

原因:Vite 將 index.html 視為原始碼的一部分,可以直接引用 src/ 中的模組。


配置檔案

vite.config.js

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

export default defineConfig({
  // 插件
  plugins: [vue()],

  // 開發伺服器配置
  server: {
    port: 3000,              // 埠號
    open: true,              // 自動開啟瀏覽器
    cors: true,              // 啟用 CORS

    // Proxy 代理設定
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  },

  // 路徑別名
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components')
    }
  },

  // 建構配置
  build: {
    outDir: 'dist',          // 輸出目錄
    assetsDir: 'assets',     // 靜態資源目錄
    sourcemap: false,        // 是否生成 source map
    minify: 'terser',        // 壓縮器('terser' | 'esbuild')

    // Rollup 選項
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['vue', 'vue-router'],  // 分離第三方庫
        }
      }
    }
  },

  // 環境變數前綴
  envPrefix: 'VITE_',

  // CSS 配置
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import "@/styles/variables.scss";`
      }
    }
  }
})

TypeScript 配置

// vite.config.ts
import { defineConfig } from 'vite'
import type { UserConfig } from 'vite'

export default defineConfig({
  // ...
} as UserConfig)

開發伺服器

啟動開發伺服器

npm run dev
# 或
vite

# 指定埠號
vite --port 3000

# 指定 host(允許外部訪問)
vite --host

開發伺服器特性

1. 即時熱更新(HMR)

// main.js
if (import.meta.hot) {
  // 接受自身模組的更新
  import.meta.hot.accept((newModule) => {
    console.log('模組已更新')
  })

  // 接受依賴模組的更新
  import.meta.hot.accept('./some-module.js', (newModule) => {
    // 更新邏輯
  })

  // 清理副作用
  import.meta.hot.dispose(() => {
    console.log('模組即將被替換')
  })
}

2. 開發模式 API

// 判斷是否為開發模式
if (import.meta.env.DEV) {
  console.log('開發模式')
}

// 判斷是否為生產模式
if (import.meta.env.PROD) {
  console.log('生產模式')
}

// 取得環境變數
console.log(import.meta.env.VITE_API_URL)

建構與優化

建構生產版本

npm run build
# 或
vite build

# 預覽建構結果
npm run preview
# 或
vite preview

建構輸出

dist/
├── index.html                    # HTML(已壓縮)
├── assets/
│   ├── index-a1b2c3.js          # JS(已壓縮、hash 命名)
│   ├── index-d4e5f6.css         # CSS(已提取、壓縮)
│   └── logo-g7h8i9.png          # 圖片(已優化)
└── favicon.ico

建構優化選項

// vite.config.js
export default defineConfig({
  build: {
    // 1. 分割程式碼
    rollupOptions: {
      output: {
        manualChunks(id) {
          // 將 node_modules 分離
          if (id.includes('node_modules')) {
            return 'vendor'
          }
        }
      }
    },

    // 2. 壓縮選項
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,  // 移除 console
        drop_debugger: true  // 移除 debugger
      }
    },

    // 3. 設定警告大小限制
    chunkSizeWarningLimit: 500,  // KB

    // 4. CSS 程式碼分割
    cssCodeSplit: true,

    // 5. 資源內聯閾值
    assetsInlineLimit: 4096  // 小於 4KB 的資源內聯為 base64
  }
})

插件系統

官方插件

# Vue
npm install -D @vitejs/plugin-vue

# React
npm install -D @vitejs/plugin-react

# React with SWC(更快)
npm install -D @vitejs/plugin-react-swc

使用插件

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import legacy from '@vitejs/plugin-legacy'

export default defineConfig({
  plugins: [
    vue(),

    // 支援舊版瀏覽器
    legacy({
      targets: ['defaults', 'not IE 11']
    })
  ]
})

常用社群插件

# 自動引入元件
npm install -D unplugin-vue-components

# 自動引入 API
npm install -D unplugin-auto-import

# SVG 元件化
npm install -D vite-plugin-svg-icons

# 壓縮
npm install -D vite-plugin-compression

# PWA
npm install -D vite-plugin-pwa

# 檢查器
npm install -D vite-plugin-inspect

環境變數

定義環境變數

# .env
VITE_APP_TITLE=My App
VITE_API_URL=http://localhost:8080

# .env.development(開發環境)
VITE_API_URL=http://localhost:8080

# .env.production(生產環境)
VITE_API_URL=https://api.production.com

使用環境變數

// main.js
console.log(import.meta.env.VITE_APP_TITLE)
console.log(import.meta.env.VITE_API_URL)

// 內建變數
console.log(import.meta.env.MODE)       // 'development' | 'production'
console.log(import.meta.env.DEV)        // boolean
console.log(import.meta.env.PROD)       // boolean
console.log(import.meta.env.SSR)        // boolean
console.log(import.meta.env.BASE_URL)   // string

TypeScript 支援

// env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  readonly VITE_API_URL: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

常用指令

# 開發
vite                    # 啟動開發伺服器
vite --host             # 允許外部訪問
vite --port 3000        # 指定埠號
vite --open             # 自動開啟瀏覽器

# 建構
vite build              # 建構生產版本
vite build --watch      # 監聽模式建構
vite build --mode staging  # 使用特定環境

# 預覽
vite preview            # 預覽建構結果
vite preview --port 5000   # 指定預覽埠號

# 優化
vite optimize           # 預建構依賴

最佳實踐

1. 使用路徑別名

// vite.config.js
import path from 'path'

export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@utils': path.resolve(__dirname, './src/utils')
    }
  }
})

// 使用
import Button from '@components/Button.vue'
import { formatDate } from '@utils/date.js'

2. 動態引入(程式碼分割)

// 動態引入元件
const AdminPanel = () => import('./components/AdminPanel.vue')

// 路由懶載入
const routes = [
  {
    path: '/admin',
    component: () => import('./views/Admin.vue')
  }
]

3. 資源處理

// 引入圖片
import logo from './assets/logo.png'

// 使用 ?url 取得 URL
import imageUrl from './assets/image.png?url'

// 使用 ?raw 取得原始內容
import svgRaw from './assets/icon.svg?raw'

// 使用 ?inline 內聯為 base64
import imageInline from './assets/small.png?inline'

4. Glob 批量引入

// 引入多個模組
const modules = import.meta.glob('./modules/*.js')
// 等同於:
// {
//   './modules/foo.js': () => import('./modules/foo.js'),
//   './modules/bar.js': () => import('./modules/bar.js')
// }

// 立即引入(非動態)
const modules = import.meta.glob('./modules/*.js', { eager: true })

5. JSON 命名引入

// 引入整個 JSON
import json from './data.json'

// 引入特定欄位
import { version } from './package.json'

與 Webpack 比較

特性 Vite Webpack
啟動速度 ⚡ 幾乎瞬間(大專案也快) 🐌 大專案可能需要數分鐘
HMR 速度 ⚡ 毫秒級 🐌 秒級
建構速度 🚀 快(使用 esbuild + Rollup) 🐌 較慢
開發模式 原生 ESM,按需編譯 打包整個應用
配置複雜度 ✅ 簡單,開箱即用 ❌ 複雜,需要大量配置
生態系統 🆕 新,但快速成長 📚 成熟,非常豐富
瀏覽器支援 現代瀏覽器(可用 legacy 插件支援舊版) 支援所有瀏覽器
適用場景 現代 Web 應用 所有類型專案

何時選擇 Vite?

✅ 適合:

  • 新專案
  • 現代瀏覽器為主
  • 追求開發體驗
  • Vue / React / Svelte 專案

❌ 不適合:

  • 需要支援 IE11
  • 高度客製化的 Webpack 配置
  • 特殊的載入器需求
  • 遺留專案遷移

疑難排解

1. 依賴預建構問題

# 清除快取並重新預建構
rm -rf node_modules/.vite
vite --force

2. 埠號被佔用

// vite.config.js
export default defineConfig({
  server: {
    port: 3000,
    strictPort: false  // 自動嘗試下一個可用埠號
  }
})

3. CORS 問題

// vite.config.js
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,  // 解決 CORS
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

4. 大檔案警告

// vite.config.js
export default defineConfig({
  build: {
    chunkSizeWarningLimit: 1000  // 提高限制到 1000 KB
  }
})

參考資源


總結

Vite 的優勢

極速開發體驗:冷啟動快、HMR 快 ✅ 現代化:原生 ESM、現代瀏覽器優先 ✅ 配置簡單:開箱即用,最小化配置 ✅ 生態豐富:支援主流框架,插件生態快速成長 ✅ 優化建構:使用 Rollup,自動優化

快速記憶

Vite = 速度 + 簡單 + 現代化

開發時:原生 ESM,按需編譯
建構時:Rollup,自動優化
結果:極速的開發體驗 + 優化的生產輸出


建立日期:2024-11-14 最後更新:2025-11-18 適用版本:Vite 5.x

🔗相關文章