Vercel 部署 Vue 完整教學|2025 Vue 3 + Vite 上線指南
Vue 專案開發完成,準備上線了嗎?
部署到 Vercel,3 分鐘就能讓全世界看到你的作品。
免費、快速、自動化。
這篇文章教你如何把 Vue 應用部署到 Vercel。
為什麼選擇 Vercel?
Vercel 對 Vue 的支援
| 優勢 | 說明 |
|---|---|
| 自動偵測 | 自動識別 Vue、Vite 專案 |
| 零配置 | 不需要額外設定 |
| 全球 CDN | 靜態資源快速載入 |
| Preview 部署 | 每個 PR 都有預覽網址 |
| 免費額度 | 個人專案免費使用 |
支援的 Vue 設定
- Vue 3 + Vite(推薦)
- Vue 3 + Vue CLI
- Vue 2 + Vue CLI
- Nuxt.js(有專門支援)
專案準備
Vue 3 + Vite(推薦)
專案結構:
my-vue-app/
├── public/
├── src/
│ ├── App.vue
│ ├── main.js
│ └── router/
│ └── index.js
├── index.html
├── package.json
└── vite.config.js
package.json:
{
"name": "my-vue-app",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.2.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.0"
}
}
Vue CLI 專案
專案結構:
my-vue-app/
├── public/
│ └── index.html
├── src/
│ ├── App.vue
│ └── main.js
├── package.json
└── vue.config.js
package.json:
{
"name": "my-vue-app",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
}
}
本機測試
# 執行 build
npm run build
# 測試 build 結果
npm run preview # Vite
# 或
npx serve dist # 通用
方法一:從 GitHub 部署
步驟一:推送到 GitHub
# 初始化 Git
git init
git add .
git commit -m "Initial commit"
# 推送到 GitHub
gh repo create my-vue-app --public --source=. --push
步驟二:連接 Vercel
- 前往 vercel.com
- 點擊 Add New → Project
- 選擇你的 GitHub Repository
- 點擊 Import
步驟三:確認設定
Vercel 會自動偵測 Vue 專案:
| 設定項目 | Vite | Vue CLI |
|---|---|---|
| Framework | Vite | Vue.js |
| Build Command | npm run build |
npm run build |
| Output Directory | dist |
dist |
步驟四:部署
點擊 Deploy,等待部署完成。
方法二:Vercel CLI 部署
安裝並登入
npm install -g vercel
vercel login
部署
cd my-vue-app
vercel
部署到 Production
vercel --prod
環境變數設定
Vite 環境變數
規則: 必須以 VITE_ 開頭
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My Vue App
使用方式:
// 在 Vue 中使用
const apiUrl = import.meta.env.VITE_API_URL;
const title = import.meta.env.VITE_APP_TITLE;
<!-- 在 template 中使用 -->
<template>
<h1>{{ appTitle }}</h1>
</template>
<script setup>
const appTitle = import.meta.env.VITE_APP_TITLE;
</script>
Vue CLI 環境變數
規則: 必須以 VUE_APP_ 開頭
# .env
VUE_APP_API_URL=https://api.example.com
VUE_APP_TITLE=My Vue App
使用方式:
const apiUrl = process.env.VUE_APP_API_URL;
在 Vercel 設定
- 專案 Settings → Environment Variables
- 新增變數(記得加前綴)
Name: VITE_API_URL
Value: https://api.example.com
Environment: Production, Preview, Development
不同環境不同值
在 Vercel 可以為不同環境設定不同值:
| 變數 | Production | Preview |
|---|---|---|
| VITE_API_URL | https://api.example.com | https://staging.api.example.com |
| VITE_DEBUG | false | true |
路由設定
Vue Router History 模式
Vue Router 使用 history 模式需要設定重寫規則。
vercel.json:
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}
Router 設定範例
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('@/views/Home.vue') },
{ path: '/about', component: () => import('@/views/About.vue') },
{ path: '/contact', component: () => import('@/views/Contact.vue') },
{ path: '/:pathMatch(.*)*', component: () => import('@/views/NotFound.vue') },
],
});
export default router;
Hash 模式(不需要額外設定)
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory(),
routes: [
// ...
],
});
網址會變成 https://example.com/#/about
效能優化
路由懶載入
// 使用動態 import
const routes = [
{
path: '/dashboard',
component: () => import('@/views/Dashboard.vue'),
},
{
path: '/settings',
component: () => import('@/views/Settings.vue'),
},
];
元件懶載入
<script setup>
import { defineAsyncComponent } from 'vue';
const HeavyComponent = defineAsyncComponent(() =>
import('@/components/HeavyComponent.vue')
);
</script>
<template>
<Suspense>
<HeavyComponent />
<template #fallback>Loading...</template>
</Suspense>
</template>
Vite Build 優化
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router'],
utils: ['lodash', 'axios'],
},
},
},
},
});
圖片優化
<template>
<!-- 延遲載入圖片 -->
<img src="/image.jpg" loading="lazy" alt="描述" />
<!-- 使用 WebP -->
<picture>
<source srcset="/image.webp" type="image/webp" />
<img src="/image.jpg" alt="描述" />
</picture>
</template>
設定快取標頭
// vercel.json
{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}
API 整合
使用 Axios
// src/api/index.js
import axios from 'axios';
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
timeout: 10000,
});
export default api;
// 使用
import api from '@/api';
const { data } = await api.get('/users');
使用 Fetch
// src/composables/useFetch.js
import { ref } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(true);
fetch(`${import.meta.env.VITE_API_URL}${url}`)
.then(res => res.json())
.then(json => {
data.value = json;
loading.value = false;
})
.catch(err => {
error.value = err;
loading.value = false;
});
return { data, error, loading };
}
API 代理
// vercel.json
{
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://api.example.com/:path*"
}
]
}
這樣前端可以直接呼叫 /api/users,避免 CORS 問題。
常見問題排解
問題一:Build 失敗
錯誤訊息:
Error: Cannot find module '@vitejs/plugin-vue'
解決方法:
npm install @vitejs/plugin-vue --save-dev
問題二:頁面空白
可能原因:
- 路由設定問題
- Base URL 設定錯誤
檢查 vite.config.js:
export default defineConfig({
base: '/', // 確保是 /
plugins: [vue()],
});
問題三:路由 404
原因: SPA 需要 fallback 到 index.html
解決方法:
建立 vercel.json:
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
問題四:環境變數讀不到
檢查項目:
- 是否有
VITE_前綴 - 是否重新部署了
- 是否在 Vercel Dashboard 設定
偵錯:
console.log('API URL:', import.meta.env.VITE_API_URL);
console.log('Mode:', import.meta.env.MODE);
console.log('All:', import.meta.env);
問題五:Alias 路徑錯誤
錯誤訊息:
Cannot find module '@/components/Header.vue'
確認 vite.config.js:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});
Pinia 狀態管理
基本設定
// src/stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
},
});
環境相關的 Store
// src/stores/config.js
import { defineStore } from 'pinia';
export const useConfigStore = defineStore('config', {
state: () => ({
apiUrl: import.meta.env.VITE_API_URL,
debug: import.meta.env.VITE_DEBUG === 'true',
}),
});
部署檢查清單
部署前
- [ ]
npm run build成功 - [ ] 本機預覽正常
- [ ] 環境變數已設定
- [ ] vercel.json 路由設定正確
- [ ] 沒有 console.log 洩漏敏感資訊
部署後
- [ ] 首頁正常顯示
- [ ] 所有路由可訪問
- [ ] API 連線正常
- [ ] 圖片和資源載入正常
- [ ] HTTPS 正常
常見問題 FAQ
Q1:Vue 2 還能部署嗎?
可以,Vercel 支援 Vue 2。
但建議升級到 Vue 3,因為:
- Vue 2 已進入維護模式
- Vue 3 效能更好
- 新套件可能不支援 Vue 2
Q2:Vite 和 Vue CLI 哪個好?
2025 年建議使用 Vite:
- 開發伺服器啟動更快
- HMR 更快
- Build 更快
- Vue 官方推薦
Q3:可以部署 SSR 嗎?
純 Vue 專案是 SPA(客戶端渲染)。
如果需要 SSR,建議使用 Nuxt.js。
Q4:免費方案夠用嗎?
對個人專案和小型網站絕對夠用:
- 100 GB/月 頻寬
- 6,000 Build 分鐘/月
- 無限專案
Q5:如何設定自訂網域?
- Settings → Domains
- 新增網域
- 設定 DNS
Vercel 部署失敗?
Build Error、環境變數、自訂網域,我們幫你快速排除問題。