你可能已经把博客搭好了,但每次发文都还要“打包-上传-部署”?今天我们来点优雅的:写完 Markdown,一把 git push,网站自动更新,全程无手动。本文用 Hexo + GitHub + Vercel 的经典三件套,手把手带你把自动化这件事变得像呼吸一样自然。整篇文章以已上线的 jiangxu.net 为例,顺带聊聊背后的技术原理。
术语速查表(新手友好)
| 术语 | 解释 |
|---|---|
| Webhook | 当仓库发生事件(如 push)时,GitHub 主动向一个 URL 发送 HTTP 请求,通知第三方(这里是 Vercel)触发自动流程。 |
| 原子发布 | 新版本先在后台完整构建并准备好,随后用一次“瞬间切换”替换旧版本;全站要么是旧版,要么是新版,不会出现一半新一半旧;出问题可秒级回滚。 |
| CDN | 内容分发网络,把静态资源复制到多个边缘节点,用户就近访问,延迟更低、带宽更大、稳定性更好。 |
| 全球 CDN | 覆盖全球多个区域的 CDN,让不同地区的访客都能就近获取内容;Vercel 发布会把 public/ 分发到其全球边缘节点。 |
| 根域(apex) | 不带子域的域名,例如 jiangxu.net。通常用 A 记录指向服务商提供的 IP(如 76.76.21.21)。 |
| www 子域 | 带 www 的子域,例如 www.jiangxu.net。通常用 CNAME 指向托管商域名(如 cname.vercel-dns.com),并可在托管侧设置重定向到根域或相反方向。 |
| 静态化 | 预先把页面生成成静态的 HTML/CSS/JS 文件(例如 Hexo 的 hexo generate 生成 public/),上线时无需后端渲染。 |
| PR(Pull Request) | 在 Git 平台上发起的“合并申请”,用于变更的讨论与审核;每个 PR 在 Vercel 都会有独立的 Preview 环境,方便预览和评审。 |
小注:
- A 记录 = 把域名直接指向一个 IPv4 地址(IPv6 用 AAAA)。例:
jiangxu.net -> A 76.76.21.21。- CNAME = 给域名起“别名”,把一个域名指向另一个域名,再由对方域名解析到 IP。例:
www.jiangxu.net -> CNAME cname.vercel-dns.com。- 通常根域名用 A 记录,
www子域用 CNAME(少数 DNS 支持根域“平展”别名,叫 ALIAS/ANAME)。
我们要得到什么
- 写文章 →
git push→ 几十秒后网站自动发布 - 自定义域名
jiangxu.net,含www子域 - 全站 CDN 加速、原子发布(不会出现“构建到一半页面 404”的尴尬)
项目现状(以本仓库为例)
本项目是一个标准 Hexo 项目,核心配置如下:
1 | # _config.yml(节选) |
1 | // package.json(节选) |
注意:项目里虽然安装了 hexo-deployer-git,但我们将由 Vercel 来托管与发布静态文件,不必再用 hexo deploy 推到 GitHub Pages。Vercel 在构建时会执行 npm ci && npm run build(或者你自定义的命令),生成 public/ 目录并发布。
架构一图流(你可以先收藏再细看)
1 | flowchart LR |
一步步搭起来
1)把 Hexo 项目放到 GitHub
如果你已经有仓库,跳过本节。否则:
1 | git init |
2)在 Vercel 里“导入”这个仓库
- 用 GitHub 账号登录 Vercel。
- New Project → 选中你的仓库 → Import。
- 配置:
- Framework Preset:选择 Hexo(或手动)
- Install Command:默认(推荐
npm ci) - Build Command:
hexo generate - Output Directory:
public
- 点击 Deploy。几十秒后会拿到一个
*.vercel.app的临时域名。
此后每次 push,Vercel 都会自动构建与发布。开分支提 PR 也会生成“预览环境”,方便你把文章和样式改动发给朋友“云审稿”。
3)绑定自定义域名 jiangxu.net
在项目 → Settings → Domains 里添加 jiangxu.net 与 www.jiangxu.net,按提示去域名注册商配置 DNS:
- 根域(apex):添加 A 记录 → 指向
76.76.21.21(Vercel 的 Anycast IP) www子域:添加 CNAME → 指向cname.vercel-dns.com
等 DNS 生效后,Vercel 会自动签发 HTTPS 证书(Let’s Encrypt)。如果你想把 www 跳转到根域(或反过来),在 Vercel 域名设置里点一下“Redirect”即可。
顺带一提,Hexo 的 _config.yml 已把 url 设为 https://jiangxu.net/:
1 | url: https://jiangxu.net/ |
这会影响站内链接、RSS、Canonical 等生成,记得与实际域名保持一致。
4)写作与发布流程(真正的“自动化”)
日常只做三步:
1 | hexo new "我的新文章" # 生成草稿/文章 |
然后泡杯咖啡,等 Vercel 自动完成构建与发布。
这些技术原理,知其所以然更香
- Webhooks:Vercel 与 GitHub 通过 Webhooks 通知协作。仓库有新提交 → 触发一次构建。
- CI/CD:Vercel 内置流水线,拉代码 → 安装依赖 → 执行
hexo generate→ 上传public/。 - 静态化:Hexo 预渲染为纯静态文件(HTML/CSS/JS),天然适合 CDN,延迟低、可承载高并发。
- 原子发布:新版本构建完成后一次性切换,不会出现“部分页面旧、部分页面新”。
- 缓存与失效:CDN 命中为王。新版本发布后 Vercel 会做缓存失效处理,通常无需你手动清缓存。
- 预览环境:每个 PR 一条独立的 Preview URL,不影响生产站点。
常用实践与“避坑锦囊”
- 资源管理:
post_asset_folder: true已开启。用source/_posts/我的新文章/管理配图,Markdown 里直接相对路径引用,迁移/重构都不怕。 - 相对链接:
relative_link: true可减少跨域/环境差异带来的链接问题。 - 主题与样式:当前主题为
pure。如果你改了主题静态资源路径,别忘了清缓存再构建:npm run clean && npm run build。 - 不混用两套部署:既然用了 Vercel,就不必再通过
hexo-deployer-git推 GitHub Pages,避免“双主发布”互相覆盖。 - Node 与依赖:为一致的构建结果,建议在 Vercel 的 Project Settings → Environment 里设置
NODE_VERSION(如 18/20)并使用npm ci。
DNS 解析小抄(再来一张图)
1 | graph TD |
收尾:写作体验从“还行”升到“上头”
现在,发文这件事就像发朋友圈:写完点发送(push 一下),剩下交给机器。你要做的,不过是保持输出而已。
如果你想继续进阶:
- 在 PR 的 Preview 环境里做 A/B 尝试(比如新主题、新排版)
- 接入评论系统(如 Gitalk/Giscus),在 Vercel 环境变量里配置 Token
- 在构建脚本里加上字数统计、站点地图、SEO 插件
愿你写得开心,站点常新。jiangxu.net 我们下次见!
面试实战自述(段落版)
直白说,我把写博客变成了“像发朋友圈一样简单”:我在本地用 Markdown 写完,git push 一下,几十秒后网站就自动更新。我用 Hexo 把文章提前生成为静态网页(不需要服务器算),代码放在 GitHub,Vercel 负责自动构建和发布,并把网页分发到全球的 CDN 节点,让离用户近的机器来服务,访问更快、更稳定。
它的工作流程很简单:我提交代码后,GitHub 会“提醒”Vercel(这叫 Webhook,就是一次通知)。Vercel 自动安装依赖并运行 hexo generate 生成网页文件,然后一次性把新版本切换上线(原子发布:不是一点点替换,而是“全部准备好再整体切换”,因此不会出现“有的页面新有的页面旧”)。域名这块,我把根域名和 www 都指到了 Vercel,证书是自动签发的,整站都是 HTTPS。
为什么这样做?因为博客是“读多写少”,静态页面最合适:速度快、成本低、出错少。
我为稳定性做了几个小细节:固定 Node 版本并用 npm ci 保证“在哪构建都一样”;文章的配图和资源放在同名文件夹并用相对路径,避免换主题或迁移时出现 404;DNS 按要求配置了根域名的 A 记录和 www 的 CNAME,确保国内外访问都能走最近的节点。
这个项目让我把零散的名词(Webhook、CI/CD、静态化、原子发布、CDN、DNS)串成了一个能跑起来的系统。我能现场演示:改一行文案、git push,几秒钟后就能拿到一个预览地址;确认没问题,再合并上线。如果出问题,我也知道怎么通过日志定位,并在需要时一键回退。