从零开始:将 Vite + React 项目部署到 GitHub Pages 完全指南

·
开发工具 Github Action Github Pages January 27, 2025

从零开始:将 Vite + React 项目部署到 GitHub Pages 完全指南

本教程基于实际操作经验编写,从"为什么"到"怎么做",带你彻底理解整个部署流程。

写在前面

你写了一个网页应用,想让朋友也能访问。最简单的方式就是部署到 GitHub Pages —— 免费、稳定、还自带 HTTPS。

但当你真正动手时,可能会遇到一堆问题:

  • 什么是 Git?什么是 GitHub?它们有什么区别?
  • GitHub Pages 和 GitHub Actions 又是什么关系?
  • 为什么我的 React 项目不能直接部署,还要配置一堆东西?

这篇教程会回答所有这些问题。读完后,你不仅能成功部署项目,还能理解每一步背后的原理。


第一章:理解基本概念

在开始之前,我们先搞清楚几个核心概念。这些概念相互关联,理解它们之间的关系非常重要。

1.1 Git:你的代码时光机

想象一下,你在写一篇重要的文章。你可能会这样保存:

论文_v1.doc
论文_v2.doc
论文_v2_修改.doc
论文_最终版.doc
论文_最终版_真的最终.doc

这种方式有很多问题:文件越来越多、不知道每个版本改了什么、想回到某个状态很困难。

Git 就是为了解决这个问题而生的。它是一个版本控制系统,能够:

  • 记录每一次修改的内容
  • 随时回到任何一个历史版本
  • 查看"谁在什么时候改了什么"

使用 Git 后,你只需要一个文件夹,所有历史版本都被 Git 默默记录在 .git 隐藏目录里。

1.2 GitHub:Git 的云端管家

Git 把版本历史存在你自己电脑上,但如果:

  • 电脑坏了怎么办?
  • 想和别人协作怎么办?
  • 想在另一台电脑上继续工作怎么办?

GitHub 就是一个云端平台,专门用来存放 Git 仓库。你可以把本地的代码"推送"到 GitHub,它就安全地保存在云端了。

💡 简单记忆:Git 是工具,GitHub 是平台。就像 "视频" 和 "YouTube" 的关系。

1.3 GitHub Pages:免费的网站托管

GitHub 除了存代码,还提供了一个福利:GitHub Pages。

它能把你仓库里的静态文件(HTML、CSS、JS)变成一个真正可访问的网站。而且完全免费,自带 https://用户名.github.io/仓库名 的域名。

1.4 GitHub Actions:自动化机器人

这是一个稍微高级的概念,但对于现代前端项目来说必不可少。

问题来了:你写的是 React + TypeScript 代码,但浏览器只认识 HTML、CSS、JavaScript。

你写的代码          浏览器需要的
───────────         ────────────
App.tsx       →     index.js
styles.scss   →     styles.css
组件化代码     →     打包后的单文件

中间这个转换过程叫做构建(Build)。在本地,你运行 npm run build,Vite 就会帮你完成构建,生成 dist 文件夹。

但 GitHub Pages 只是一个静态文件托管服务,它不会帮你运行 npm run build。

这就是 GitHub Actions 的作用:它是一个自动化服务,可以在 GitHub 的服务器上执行命令。每当你推送代码,它就自动:

  1. 下载你的代码
  2. 安装依赖 (npm install)
  3. 执行构建 (npm run build)
  4. 把构建结果部署到 Pages

相当于你有了一个 24 小时在线的机器人,帮你做重复性工作。

1.5 概念关系图

让我们用一张图来总结这些概念的关系:

┌─────────────────────────────────────────────────────────────────┐
│                         你的电脑                                 │
│   ┌─────────────┐                                               │
│   │   项目文件    │ ──── git add/commit ────→ 本地 Git 仓库       │
│   │  (源代码)    │                              (.git 目录)      │
│   └─────────────┘                                               │
└──────────────────────────────┬──────────────────────────────────┘
                               │ git push
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                         GitHub                                   │
│   ┌─────────────┐      ┌─────────────┐      ┌─────────────┐     │
│   │  远程仓库    │ ───→ │   Actions   │ ───→ │   Pages     │     │
│   │  (存储代码)  │      │  (自动构建)  │      │ (托管网站)   │     │
│   └─────────────┘      └─────────────┘      └─────────────┘     │
└─────────────────────────────────────────────────────────────────┘
                                                     │
                                                     ▼
                                            用户访问的网站
                                    https://xxx.github.io/项目名/

第二章:Git 操作详解

现在概念清楚了,让我们开始实际操作。

2.1 初始化仓库

git init

这条命令在当前目录创建一个 .git 隐藏文件夹。从此刻起,Git 开始追踪这个目录。

执行前:普通文件夹
执行后:Git 仓库

你可以用 ls -la(Mac/Linux)或 dir /a(Windows)查看这个隐藏目录。

2.2 Git 的三个区域

在理解后续命令前,必须先理解 Git 的三个区域:

┌─────────────┐    git add    ┌─────────────┐   git commit   ┌─────────────┐
│   工作区     │ ───────────→ │   暂存区     │ ─────────────→ │   版本库     │
│ Working Dir │              │    Stage    │                │ Repository  │
│             │              │             │                │             │
│  你编辑的    │              │ 准备提交的   │                │  已保存的    │
│  实际文件    │              │  文件快照    │                │  历史版本    │
└─────────────┘              └─────────────┘                └─────────────┘

为什么要有"暂存区"这个中间层?

想象你改了 10 个文件,但只想提交其中 3 个。暂存区让你可以精确控制"这次提交包含哪些改动"。

2.3 添加文件到暂存区

git add .

这里的 . 表示"当前目录的所有文件"。执行后,所有改动的文件都进入暂存区,等待被提交。

你也可以只添加特定文件:

git add src/App.tsx
git add package.json

2.4 提交到版本库

git commit -m "这里写提交信息"

这条命令把暂存区的内容永久保存到版本库。每次提交都会生成一个唯一的 ID(如 c7d1fef),你可以通过这个 ID 回到这个版本。

提交信息很重要:好的提交信息能让你(和同事)知道这次改动是干什么的。

# ❌ 不好的提交信息
git commit -m "update"
git commit -m "fix"

# ✅ 好的提交信息
git commit -m "修复登录页面样式错位问题"
git commit -m "添加用户头像上传功能"

2.5 .gitignore:告诉 Git 忽略什么

有些文件不应该提交到仓库:

  • node_modules/:几万个文件,又大又能重新安装
  • dist/:构建产物,每次构建都会重新生成
  • .env:包含密钥等敏感信息

在项目根目录创建 .gitignore 文件:

node_modules/
dist/
.env
.env.local

Git 会自动忽略这些文件,不会追踪它们的变化。


第三章:连接 GitHub

本地仓库准备好了,接下来要把它推送到 GitHub。

3.1 GitHub CLI:命令行操作 GitHub

传统方式需要在网页上操作,但 GitHub CLI(命令行工具)让一切变得简单。

首先检查是否安装:

gh --version

如果没安装,去 https://cli.github.com/ 下载。

3.2 登录认证

gh auth login

按提示操作:

  1. 选择 GitHub.com
  2. 选择 HTTPS
  3. 选择 Login with a web browser
  4. 复制终端显示的一次性代码
  5. 浏览器会打开,粘贴代码完成授权

授权成功后,GitHub CLI 就能代表你执行操作了。

3.3 创建远程仓库并推送

gh repo create 仓库名 --private --source=. --push

这一条命令做了四件事:

  1. 在 GitHub 上创建名为"仓库名"的私有仓库
  2. 把当前目录(--source=.)设为源代码
  3. 自动配置远程连接
  4. 推送代码(--push)

参数说明:

  • --private:私有仓库(只有你能看到)
  • --public:公开仓库(所有人能看到)

第四章:配置 GitHub Actions

现在代码在 GitHub 了,我们来配置自动部署。

4.1 创建工作流文件

在项目根目录创建 .github/workflows/deploy.yml:

项目目录/
├── .github/
│   └── workflows/
│       └── deploy.yml    ← 创建这个文件
├── src/
├── package.json
└── ...
💡 目录名必须是 .github/workflows,这是 GitHub 约定的位置。

4.2 工作流文件详解

下面是完整的配置文件,我会逐段解释每一部分:

name: Deploy to GitHub Pages

这只是给工作流起个名字,会显示在 GitHub Actions 页面。

on:
  push:
    branches: ['master']
  workflow_dispatch:

触发条件:

  • push + branches: ['master']:当有代码推送到 master 分支时触发
  • workflow_dispatch:允许在 GitHub 网页上手动触发
permissions:
  contents: read
  pages: write
  id-token: write

权限设置:

  • contents: read:允许读取仓库内容
  • pages: write:允许写入 GitHub Pages
  • id-token: write:用于身份验证
concurrency:
  group: 'pages'
  cancel-in-progress: true

并发控制:如果新的部署开始,取消正在进行的旧部署。避免冲突。

jobs:
  build:
    runs-on: ubuntu-latest

定义任务:创建一个名为 build 的任务,运行在最新版 Ubuntu 虚拟机上。

💡 GitHub 会为每次运行临时创建一个全新的虚拟机,运行完就销毁。
    steps:
      - name: Checkout
        uses: actions/checkout@v4

第一步:检出代码。虚拟机是空的,需要把你的代码从仓库"下载"进去。actions/checkout@v4 是 GitHub 官方提供的动作(Action)。

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

第二步:安装 Node.js。虚拟机虽然有基础环境,但不一定有你需要的 Node 版本。这一步安装 Node 20,并启用 npm 缓存加速后续安装。

      - name: Install dependencies
        run: npm install

第三步:安装项目依赖。读取 package.json,下载所有依赖包。

      - name: Build
        run: npm run build

第四步:构建项目。执行 Vite 的构建命令,把源代码编译成静态文件,输出到 dist 目录。

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

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

第五、六步:准备部署。配置 Pages 并上传 dist 目录作为"产物"。

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

第二个任务:部署。needs: build 表示必须等 build 任务完成才能开始。这个任务把上一步上传的产物发布到 GitHub Pages。

4.3 关于 package-lock.json

你可能注意到了 cache: 'npm' 这个配置。它需要读取 package-lock.json 来确定缓存键。

什么是 package-lock.json?

当你运行 npm install 时,npm 会:

  1. 读取 package.json 里的依赖列表
  2. 下载依赖,并记录每个包的精确版本号到 package-lock.json

这个文件确保了"任何人在任何时候安装,都得到完全相同的依赖版本"。

如果没有这个文件,Actions 会报错:

Dependencies lock file is not found

解决方法:

npm install                    # 这会自动生成 package-lock.json
git add package-lock.json
git commit -m "添加 package-lock.json"
git push

4.4 启用 GitHub Pages

工作流文件创建好了,还需要在 GitHub 上启用 Pages:

gh api repos/你的用户名/仓库名/pages -X POST -f build_type=workflow

这条命令告诉 GitHub:"我要用 Actions 工作流来部署 Pages"。


第五章:自定义域名

默认的 xxx.github.io/项目名 地址太长?你可以配置自己的域名。

5.1 DNS 是什么?

当你在浏览器输入 google.com,电脑需要知道这个域名对应哪个服务器(IP 地址)。DNS(域名系统)就像一本电话簿,负责把域名"翻译"成 IP 地址。

你输入: journal.hongrui-fu.online
   │
   ▼ DNS 查询
   │
得到: 185.199.108.153 (GitHub 服务器)
   │
   ▼ 发送请求
   │
显示: 你的网站

5.2 常见 DNS 记录类型

记录类型作用值的格式例子
A域名 → IP 地址IP 地址185.199.108.153
CNAME域名 → 另一个域名域名xunxun2001.github.io
TXT存储文本(常用于验证)任意文本github-pages-verify=xxx

5.3 域名验证 vs 域名指向

这是很多人混淆的地方:

TXT 记录(验证):

  • 作用:证明"这个域名是我的"
  • 给谁看:GitHub
  • 不设置会怎样:GitHub 可能不让你用这个域名

A/CNAME 记录(指向):

  • 作用:告诉访客"这个域名的服务器在哪"
  • 给谁看:全世界的 DNS 系统
  • 不设置会怎样:访客无法访问你的网站

两者都需要设置!

5.4 A 记录还是 CNAME?

域名类型推荐记录原因
顶级域名 (example.com)A 记录技术限制:根域名不能用 CNAME
子域名 (www.example.com)CNAME更灵活,如果 GitHub IP 变了会自动跟随
子域名 (journal.example.com)CNAME同上

GitHub Pages 的官方 IP 地址(如果用 A 记录):

185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153

这些 IP 非常稳定,GitHub 保证不会轻易变更。

5.5 配置步骤(以子域名为例)

假设你想用 journal.hongrui-fu.online:

步骤 1:GitHub 端设置

gh api repos/你的用户名/仓库名/pages -X PUT -f cname="journal.hongrui-fu.online"

步骤 2:DNS 端设置(在你的域名服务商控制台)

添加一条 CNAME 记录:

类型名称值
CNAMEjournalxunxun2001.github.io
⚠️ Cloudflare 用户注意:把代理状态设为"仅 DNS"(灰色云朵),否则 HTTPS 可能有问题。

步骤 3:修改 Vite 配置

// vite.config.ts
export default defineConfig({
  base: '/',  // 使用自定义域名时,base 应该是 '/'
  // ...
})

为什么要改 base?

base 决定了 HTML 中资源的路径前缀:

<!-- base: '/fufu-zhizhi-journal/' -->
<script src="/fufu-zhizhi-journal/assets/index.js"></script>

<!-- base: '/' -->
<script src="/assets/index.js"></script>
  • 使用 github.io/仓库名/ 访问时,需要加仓库名前缀
  • 使用自定义域名访问时,不需要前缀

配置错误会导致资源 404,页面空白。


第六章:常见问题排查

6.1 推送被拒绝:邮箱隐私保护

错误信息:

error: GH007: Your push would publish a private email address

原因:你的 Git 配置使用了真实邮箱,GitHub 默认会阻止暴露私人邮箱。

解决方案:

# 使用 GitHub 提供的匿名邮箱
git config user.email "用户名@users.noreply.github.com"

# 重新签署最近的提交
git commit --amend --reset-author --no-edit

# 再次推送
git push

6.2 Actions 失败:找不到 lock 文件

错误信息:

Dependencies lock file is not found

解决方案:

npm install                    # 生成 package-lock.json
git add package-lock.json
git commit -m "添加 package-lock.json"
git push

6.3 页面空白

可能原因:

  1. base 配置错误(最常见)
  2. 构建失败
  3. 路由配置问题(SPA 应用)

排查步骤:

# 查看最近的 Actions 运行
gh run list

# 查看详细日志
gh run view 运行ID --log

# 检查 Pages 配置
gh api repos/用户名/仓库名/pages

6.4 自定义域名不生效

检查 DNS 是否正确:

nslookup journal.hongrui-fu.online

如果显示 找不到记录,说明 DNS 还没配置好或还在传播中。

DNS 传播通常需要几分钟,但有时可能长达 48 小时。可以用 https://dnschecker.org/ 查看全球 DNS 状态。

6.5 显示错误的域名

症状:配置了 journal.xxx.com,但显示的是 blog.old-domain.com

原因:你的主仓库 用户名.github.io 配置了旧域名,会影响所有项目。

解决方案:

# 检查主仓库配置
gh api repos/用户名/用户名.github.io/pages

# 移除旧域名
gh api repos/用户名/用户名.github.io/pages -X PUT -f cname=""

第七章:命令速查表

首次部署(完整流程)

# 1. 初始化 Git 仓库
git init
git add .
git commit -m "Initial commit"

# 2. 登录 GitHub CLI(只需一次)
gh auth login

# 3. 创建远程仓库并推送
gh repo create 仓库名 --private --source=. --push

# 4. 生成 lock 文件
npm install
git add package-lock.json
git commit -m "添加 package-lock.json"
git push

# 5. 创建 .github/workflows/deploy.yml(内容见第四章)

# 6. 提交工作流配置
git add .
git commit -m "添加 GitHub Actions 部署配置"
git push

# 7. 启用 Pages
gh api repos/用户名/仓库名/pages -X POST -f build_type=workflow

# 8. 查看部署状态
gh run watch

配置自定义域名

# GitHub 端
gh api repos/用户名/仓库名/pages -X PUT -f cname="子域名.域名.com"

# 修改 vite.config.ts 的 base 为 '/'

# 提交更改
git add .
git commit -m "配置自定义域名"
git push

# DNS 端:添加 CNAME 记录(在域名服务商控制台)
# 类型: CNAME, 名称: 子域名, 值: 用户名.github.io

日常更新

# 修改代码后
git add .
git commit -m "描述这次改了什么"
git push
# Actions 会自动构建并部署

总结

回顾一下整个流程:

  1. Git 管理代码版本,记录每次修改
  2. GitHub 在云端存储代码
  3. GitHub Actions 自动执行构建(把 TypeScript/React 编译成浏览器能运行的文件)
  4. GitHub Pages 托管构建后的静态文件,变成可访问的网站
  5. DNS 把自定义域名指向 GitHub Pages 服务器

这些工具各司其职,组合起来形成了现代前端的自动化部署流程。一旦配置好,你只需要 git push,其他的全部自动完成。

希望这篇教程能帮你真正理解整个过程,而不只是照着命令敲。下次遇到问题,你就能自己分析和解决了。


参考链接

  • GitHub Pages 官方文档
  • GitHub Actions 官方文档
  • Vite 静态部署指南
  • GitHub CLI 手册

作者:Hongrui | 最后更新:2025年12月31日

  • 趣谈网络协议:通信协议综述
  • 如何将子目录的Git仓库合并到主项目并保留提交记录?
取消回复

说点什么?
Title
1.1 Git:你的代码时光机
1.2 GitHub:Git 的云端管家
1.3 GitHub Pages:免费的网站托管
1.4 GitHub Actions:自动化机器人
1.5 概念关系图
2.1 初始化仓库
2.2 Git 的三个区域
2.3 添加文件到暂存区
2.4 提交到版本库
2.5 .gitignore:告诉 Git 忽略什么
3.1 GitHub CLI:命令行操作 GitHub
3.2 登录认证
3.3 创建远程仓库并推送
4.1 创建工作流文件
4.2 工作流文件详解
4.3 关于 package-lock.json
4.4 启用 GitHub Pages
5.1 DNS 是什么?
5.2 常见 DNS 记录类型
5.3 域名验证 vs 域名指向
5.4 A 记录还是 CNAME?
5.5 配置步骤(以子域名为例)
6.1 推送被拒绝:邮箱隐私保护
6.2 Actions 失败:找不到 lock 文件
6.3 页面空白
6.4 自定义域名不生效
6.5 显示错误的域名
首次部署(完整流程)
配置自定义域名
日常更新

© 2026 HollowのBlog. Using Typecho & Moricolor.