L18 · 部署上线:CI/CD
🎯 本节目标:将应用部署到 Vercel,配置 GitHub Actions 检查和 Vercel 自动部署
📦 本节产出:线上可访问的任务管理系统 + CI/CD 流水线 + Phase 2 总结
🔗 前置钩子:L17 的测试套件(CI 需要跑测试)
🔗 后续钩子:Phase 3 将复用工程方法,创建有后端 API 的电商应用1. 部署概览
GitHub Actions 与 Vercel 的 Git 集成默认是各自触发的,Vercel 不会自动等待这个 CI 工作流。本课在 Vercel 构建命令中也运行检查,并用分支保护约束合并。
2. 构建生产版本
2.1 构建命令
npm run buildVite 会输出优化后的静态文件到 dist/ 目录:
dist/
├── index.html # 入口 HTML
├── assets/
│ ├── index-a1b2c3d4.js # 主 JS bundle(含 hash)
│ ├── index-e5f6g7h8.css # 主 CSS bundle
│ ├── HomeView-i9j0k1l2.js # 路由懒加载 chunk
│ └── StatsView-m3n4o5p6.js # 路由懒加载 chunk
└── favicon.ico文件名中的 hash 会随对应资源内容变化。新页面引用新 URL 后,浏览器会请求新文件;HTML 的更新与缓存头仍由部署平台管理,不能只靠 hash 保证客户端立即更新。
2.2 本地预览
npm run preview
# 默认使用 http://localhost:4173,端口占用时以终端输出为准2.3 常见构建问题
| 问题 | 原因 | 解决 |
|---|---|---|
| 路由刷新 404 | SPA 只有一个 index.html | 配置服务器 fallback(见下文) |
| 环境变量缺失 | 名称、环境或构建时机不匹配 | 检查 VITE_ 前缀、目标环境,并重新构建 |
| 体积过大 | 依赖较大、重复依赖或缺少代码拆分 | 先看构建分析,再调整导入和分包 |
| 图片/字体 404 | 路径问题 | 使用 import 导入或放 public/ |
3. 部署到 Vercel
3.1 为什么选 Vercel
本课使用 Vercel 的 Vite 预设、Git 集成和预览部署。类似的静态应用也可部署到 Netlify、GitHub Pages 或 Cloudflare Pages;各平台的配额、计费和使用条款以当前官方说明为准。GitHub Pages 还需要单独处理 history 路由回退。
3.2 Vercel 部署步骤
- 连接 GitHub 仓库
# 仅在尚未设置 origin 时添加;已有远程地址可用 git remote -v 查看
git remote add origin https://github.com/你的用户名/vue-todo.git
git push -u origin main- 在 Vercel 中导入项目
访问 vercel.com → New Project → Import Git Repository → 选择仓库。
- Vercel 自动识别 Vite 项目
确认 Framework Preset 为 Vite,项目根目录指向 L01 创建的 vue-todo 应用,并设置:
- Node.js Version:
22.x,与本地和 CI 一致。 - Install Command:
npm ci,需要已提交的package-lock.json。 - Build Command:
npm run type-check:test && npm run lint:check && npm run test:run && npm run build。 - Output Directory:
dist。
type-check:test 和测试脚本来自 L17;再向 package.json 的 scripts 添加 "lint:check": "eslint ."。原脚手架的 lint 含 --fix,CI 使用不修改文件的检查命令。任一步失败都会让这次 Vercel 构建失败,不发布这次产物。
- 配置 SPA 路由 fallback
保存为项目根目录的 vercel.json:
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}这是 Vercel 官方给出的 SPA 深层链接回退配置,让 /stats 等页面地址交给 Vue Router。部署后既要直接刷新页面路径,也要检查 JS/CSS 资源能正确加载。后续接入同域 API 时,需先设计 API 路径和重写规则,不能把 API 请求当作页面回退。参见 Vite on Vercel。
3.3 环境变量
当前任务应用没有后端,不需要配置 API 地址。下一阶段接入 API 时,可在 Vercel 项目设置 → Environment Variables 为对应的 Preview / Production 环境添加:
VITE_API_URL=https://api.example.com/api
VITE_变量会进入客户端构建产物,不能存放密码、私钥或服务端密钥。修改变量后需要重新构建部署。
// 在代码中使用
const apiUrl = import.meta.env.VITE_API_URL4. GitHub Actions CI
4.1 创建 CI 工作流
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v7
- name: 安装 Node.js 22
uses: actions/setup-node@v7
with:
node-version: '22'
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 应用类型检查
run: npm run type-check
- name: 测试类型检查
run: npm run type-check:test
- name: Lint 检查
run: npm run lint:check
- name: 运行测试
run: npm run test:run
- name: 构建
run: npm run build这里的 Action 主版本依据 checkout 和 setup-node 官方示例(核对日期:2026-09-22)。使用 GitHub 托管的 ubuntu-latest runner;自托管 runner 需另外满足 Action 的运行环境要求。
4.2 PR 状态检查
先让 CI 至少运行一次,再在 GitHub 仓库的 ruleset 或分支保护设置中针对 main 配置:
✅ Require a pull request before merging
✅ Require status checks to pass before merging
✅ test(选择上面 workflow 实际产生的检查)规则会限制普通合并流程;还要根据团队权限设置是否允许管理员或其他角色绕过。它不是 Vercel 的等待开关,本课的发布检查仍由 §3.2 的构建命令执行。
5. 自动部署流程
以下假设 main 被设为 Production Branch,并且 Git 集成允许相关分支部署;来自 fork 的 PR 可能需要额外授权。详见 Vercel GitHub 集成。
| 触发事件 | 行为 |
|---|---|
Push to main | 生产环境部署(Production) |
| Push to 其他分支 | 预览环境部署(Preview) |
| Pull Request | 自动生成预览 URL |
| PR 关闭 | 不应假设立即删除已生成的部署;保留与清理由部署设置决定 |
main 分支
├── commit abc → https://vue-todo.vercel.app(生产)
└── commit def → https://vue-todo.vercel.app(更新生产)
feature/kanban 分支
├── PR #5 → https://vue-todo-pr-5.vercel.app(预览)
└── 合并后 main 产生生产部署;旧预览的保留由平台设置决定5.5 生产部署进阶
构建产物分析
上线前建议检查打包体积,避免引入过大的依赖:
# 安装分析插件
npm install -D rollup-plugin-visualizer@6在 vite.config.ts 增加导入,并把插件追加到已有 plugins 数组,保留别名等配置:
import { visualizer } from 'rollup-plugin-visualizer'
// 添加到原 plugins 数组末尾
visualizer({
filename: 'stats.html',
open: false, // CI 中不启动浏览器
gzipSize: true,
brotliSize: true,
})npm run build
# 在浏览器打开项目根目录的 stats.html 查看分析这显示的是估算的压缩体积,不代表部署平台已经启用相同压缩方式。把 stats.html 加入 .gitignore。
回滚方案
只要目标部署仍被保留,可以在 Vercel 的部署详情中使用回滚或提升到生产环境的操作;可用入口与权限、计划有关。恢复代码也可以创建一次新的 Git 提交:
# 方式 1:Vercel 仪表板
Deployments → 选择仍可用的稳定部署 → 查看 Rollback / Promote 操作
# 方式 2:Git 回滚
git revert HEAD
git push # 推送回滚提交;受保护的 main 应通过 PR 合并git revert HEAD 只撤销当前最后一条提交;合并提交或多次提交的恢复需要先确认目标。平台回滚还应检查环境变量和后端兼容性,见 Vercel Instant Rollback。
TIP
上线前运行 npm run build,再用 npm run preview 检查生产构建。部署后再验证真实域名下的路由刷新和资源请求。
6. 自定义域名(可选)
1. 在 Vercel 项目 Settings → Domains 添加自己的域名。
2. 按该项目页面提供的记录,在域名服务商配置 A / CNAME 等 DNS 记录。
3. 等待 DNS 验证和 HTTPS 证书配置完成,再访问域名检查。7. Phase 2 总结
恭喜完成 Phase 2!回顾学到的所有内容:
| 技能 | 掌握标志 |
|---|---|
| 组件架构 | 能按功能拆分组件树 |
| Vue Router | 能配置嵌套路由和守卫 |
| Pinia | 能设计多 Store + 持久化 |
| 拖拽交互 | 能实现 Kanban 看板 |
| 组件通信 | 能根据场景选择正确方案 |
| 异步加载 | 能用 Suspense 和骨架屏 |
| 自定义指令 | 能封装 DOM 操作指令 |
| 单元测试 | 能测试组件/Composable/Store |
| CI/CD | 能配置 GitHub Actions + 自动部署 |
Git 提交
git add .
git commit -m "L18: CI/CD + Vercel 部署 [Phase 2 完成]"
git tag phase-2-complete🔗 → Phase 3:全栈电商
Phase 3 切换到电商业务,复用前面学过的组件、路由、状态管理和测试方法,并引入后端 API:
- L19:Express + MongoDB 后端搭建
- L20:RESTful API 设计
- L21-L30:认证、购物车、订单、支付、WebSocket、SSR...
保留 phase-2-complete 标签作为任务应用的完整里程碑。电商使用商品、购物车和订单模型,不能直接把 Todo Store 和原测试当作同一套业务接口沿用;下一阶段需按新领域逐步替换或另建项目。