Skip to content

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 构建命令 ​

bash
npm run build

Vite 会输出优化后的静态文件到 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 本地预览 ​

bash
npm run preview
# 默认使用 http://localhost:4173,端口占用时以终端输出为准

2.3 常见构建问题 ​

问题原因解决
路由刷新 404SPA 只有一个 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 部署步骤 ​

  1. 连接 GitHub 仓库
bash
# 仅在尚未设置 origin 时添加;已有远程地址可用 git remote -v 查看
git remote add origin https://github.com/你的用户名/vue-todo.git
git push -u origin main
  1. 在 Vercel 中导入项目

访问 vercel.com → New Project → Import Git Repository → 选择仓库。

  1. 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 构建失败,不发布这次产物。

  1. 配置 SPA 路由 fallback

保存为项目根目录的 vercel.json:

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_ 变量会进入客户端构建产物,不能存放密码、私钥或服务端密钥。修改变量后需要重新构建部署。

typescript
// 在代码中使用
const apiUrl = import.meta.env.VITE_API_URL

4. GitHub Actions CI ​

4.1 创建 CI 工作流 ​

yaml
# .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 生产部署进阶 ​

构建产物分析 ​

上线前建议检查打包体积,避免引入过大的依赖:

bash
# 安装分析插件
npm install -D rollup-plugin-visualizer@6

在 vite.config.ts 增加导入,并把插件追加到已有 plugins 数组,保留别名等配置:

typescript
import { visualizer } from 'rollup-plugin-visualizer'

// 添加到原 plugins 数组末尾
visualizer({
  filename: 'stats.html',
  open: false, // CI 中不启动浏览器
  gzipSize: true,
  brotliSize: true,
})
bash
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 提交 ​

bash
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 和原测试当作同一套业务接口沿用;下一阶段需按新领域逐步替换或另建项目。