婚礼抽奖项目部署实践:GitHub Pages 与 Cloudflare

项目:年会大屏抽奖系统(React 19 + TypeScript + Vite + Tailwind CSS v4)
源码:https://github.com/bleemyoung/choujiang
场景:纯静态前端项目,数据存于浏览器 localStorage,现场投屏使用

目录

一、项目背景

婚礼现场需要一个抽奖程序,核心要求:

  • 大屏展示抽奖滚动效果
  • 后台管理参与者、奖项和中奖记录
  • 支持内定:指定某人中某个奖项(受控模式)
  • 现场投屏使用,需稳定可访问

项目本身是纯静态前端,不依赖后端服务,所有数据存储在浏览器 localStorage。这意味着部署只需要一个静态托管平台即可。

技术栈

React 19 + TypeScript + Tailwind CSS v4 + Vite 7 + Wouter(Hash 路由)+ Zustand(状态管理)+ vite-plugin-singlefile(单文件构建)

关键功能入口

功能 URL
大屏展示 http://localhost:5173/#/
后台管理 http://localhost:5173/#/admin
受控模式 URL 加 ?controlled=1(放在 # 之前)
默认密码 yihen-yckj666

受控模式(内定)

URL 添加 ?controlled=1 解锁受控模式后,CSV 导入时可识别以下列:

  • 必中奖项(奖项名称) — 内定某奖项
  • 禁止中奖(是/否) — 黑名单
  • 权重(1-10) — 中奖概率权重

二、部署方案选型

方案 成本 适用场景 推荐程度
Cloudflare Pages 免费 静态项目、绑定域名、国内访问友好 最高
GitHub Pages 免费 简单静态项目、GitHub 仓库直接发布 很推荐
腾讯云/阿里云轻量服务器 ¥68/年起 需要 Linux、Nginx、Docker 学习 可后续购买

选型结论:当前项目优先 Cloudflare Pages,原因:

  1. 成本为 0,适合临时部署
  2. 国内访问比 GitHub Pages 稳定
  3. 支持 HTTPS
  4. 全球 CDN,静态前端访问友好

三、GitHub Pages 部署

3.1 本地构建配置

vite.config.ts 关键配置:

import { viteSingleFile } from "vite-plugin-singlefile";

export default defineConfig({
  plugins: [react(), tailwindcss(), viteSingleFile()],
  base: "./",
  build: {
    outDir: "dist",
    emptyOutDir: true,
    assetsInlineLimit: 100000000, // 100MB,强制内联所有资源
  },
});

关键说明:

  • base: "./" 适配 GitHub Pages 仓库子路径部署
  • vite-plugin-singlefile 将 JS/CSS 内联进单个 HTML,便于静态托管
  • 构建产物约 1.8 MB

package.json 构建命令:

{
  "scripts": {
    "build": "tsc -b && vite build"
  }
}

3.2 GitHub Actions Workflow

仓库中实际提交的 .github/workflows/deploy.yml

name: Deploy GitHub Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 22.12.0
          cache: npm

      - name: Install
        run: npm ci

      - name: Build
        run: npm run build

      - name: Setup Pages
        uses: actions/configure-pages@v5

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy
        id: deployment
        uses: actions/deploy-pages@v4

Node 版本说明:项目使用 Vite 7,要求 Node.js 20.19+22.12+。本地 Node 20.18.2 会触发警告,workflow 中明确指定 22.12.0

3.3 仓库设置

Settings → Pages → Source → GitHub Actions

不要选择 Deploy from a branch,因为项目使用 Actions 构建并上传 dist

3.4 部署结果

  • 访问地址:https://bleemyoung.github.io/choujiang/
  • 管理后台:https://bleemyoung.github.io/choujiang/#/admin
  • 受控模式:https://bleemyoung.github.io/choujiang/?controlled=1#/admin

3.5 GitHub Pages 常见踩坑点

问题 原因 处理
Actions 成功但 Pages 未更新 Pages Source 没选 GitHub Actions Settings → Pages → Source → GitHub Actions
构建时 Vite 报 Node 版本不满足 Node 版本过低 workflow 指定 node-version: 22.12.0
部署成功但页面 404 上传目录错误 确认 path: dist
路由刷新 404 不支持 history 路由 使用 Hash 路由(#/admin
资源 404 base 配置错误 使用 base: "./" 适配子路径

3.6 阶段小结

GitHub Pages 部署配置可用,推送到 main 分支自动触发部署。但国内访问 GitHub Pages 不稳定,因此继续探索 Cloudflare 方案。

四、Cloudflare Workers 误部署(踩坑)

4.1 错误操作

在 Cloudflare Dashboard → Workers & Pages 页面选择 Create → Worker,而非 Pages

这是一个关键错误:Workers 设计用于 serverless 函数(FaaS),不适合静态资源托管。

Worker vs Pages 区别

维度 Workers Pages
定位 serverless 函数 静态站点托管
适用场景 API 接口、边缘计算 静态前端项目
构建部署 需通过 wrangler CLI 或上传脚本 支持 Git 连接自动构建 / wrangler CLI
当前项目 不适用 适用

4.2 构建失败:pnpm-lock.yaml 冲突

部署触发自动构建流水线,默认执行 pnpm install,但项目根目录下存在一个过时的残留 pnpm-lock.yaml(项目实际使用 npm),导致构建报错。

解决方法:删除 pnpm-lock.yaml,Cloudflare 自动降级为 npm install,构建成功。

4.3 误部署结果

虽然 Workers 不适合静态托管,但部署居然成功了。访问地址通过 Workers 直连可用。

4.4 踩坑总结

  1. 入口选择错误:纯静态项目应选 Pages 而非 Workers
  2. 包管理器不一致:项目应统一使用 npm 或 pnpm,清理多余 lock 文件。推荐在 package.json 中声明:
    "packageManager": "npm@10.x"
    
  3. 误打误撞 Workers 也能用,但不推荐作为正式方案

五、Cloudflare Pages 部署

5.1 部署方式

采用 wrangler CLI 直接部署。仓库根目录有 wrangler.toml 配置文件:

name = "choujiang"
compatibility_date = "2025-04-01"

[assets]
directory = "./dist"
not_found_handling = "single-page-application"

5.2 部署命令

npm run build
npx wrangler pages deploy dist --project-name=choujiang

5.3 部署说明

  • 不需要自定义域名,直接使用 Cloudflare Pages 提供的 *.pages.dev 子域名即可
  • not_found_handling = "single-page-application" 确保 SPA 路由正常(虽然本项目已用 Hash 路由规避了这个问题)
  • 部署后自动获得 HTTPS 和全球 CDN

5.4 GitHub Pages vs Cloudflare Pages 对比

维度 GitHub Pages Cloudflare Pages
国内访问 不稳定 较好
自动部署 GitHub Actions wrangler CLI / Git 连接
自定义域名 支持 支持
HTTPS 默认开启 默认开启
构建限制 每月 100 GB 带宽 每月 500 次构建(免费版)
适用场景 国际访问为主 国内访问为主

六、现场投屏实施

6.1 设备问题

  • 婚礼现场投影仪接口为 HDMI
  • 本机无 HDMI 接口,需要拓展坞转接
  • 备用机器没有 VPN,无法正常访问页面

6.2 解决方案

  • 本机通过拓展坞连接 HDMI 完成投屏展示
  • 使用 Cloudflare Pages 部署地址访问(国内可直连,无需 VPN)

6.3 注意事项

  • 后台和大屏需在同一浏览器中打开(通过 localStorage 轮询同步)
  • 现场需提前测试网络、投屏接口、备用设备
  • 建议准备离线方案(本地 npm run dev 或提前打开页面缓存)

七、经验总结

7.1 部署选型决策框架

纯静态前端项目(无后端)
├── 国内访问为主 → Cloudflare Pages(推荐)
├── 国际访问为主 → GitHub Pages / Vercel / Netlify
└── 需要自定义域名 + HTTPS → Cloudflare Pages

需要后端服务
├── 学习阶段 → 腾讯云/阿里云轻量服务器(¥68/年起)
├── 国际线路 → DigitalOcean / Vultr / Hetzner
└── 免费折腾 → Oracle Cloud Free Tier

7.2 关键踩坑记录

踩坑 原因 预防措施
Workers 误部署 入口选错 纯静态项目选 Pages,API/函数选 Workers
pnpm-lock.yaml 冲突 残留 lock 文件 统一包管理器,清理多余 lock 文件,package.json 中声明 packageManager
Node 版本警告 Vite 7 要求 20.19+/22.12+ workflow 明确指定 node-version
现场网络不通 备用设备无 VPN 提前准备网络方案,使用国内可直连的部署平台

7.3 可复用内容

  • GitHub Actions + GitHub Pages workflow 模板(已提交到仓库)
  • Cloudflare Pages wrangler.toml 配置(已提交到仓库)
  • Cloudflare Pages / GitHub Pages / 低成本服务器选型框架
  • 现场投屏设备检查清单

参考

posted @ 2026-06-08 17:48  bleemyoung  阅读(29)  评论(0)    收藏  举报