在 Cloudflare Pages 上部署 Hexo 博客全记录
本文记录从零搭建 Hexo 博客并部署到 Cloudflare Pages 的完整过程,包含踩坑记录和最终可用配置。
一、技术选型
| 组件 | 选择 | 理由 |
|---|---|---|
| 静态站点生成器 | Hexo | 生态成熟,中文友好 |
| 主题 | NexT.Gemini | 简洁、功能丰富、维护活跃 |
| 托管平台 | Cloudflare Pages | 免费、全球 CDN、自定义域名含 SSL |
二、本地初始化
npm install -g hexo-cli |
_config.yml 指定主题:
theme: next |
新建 _config.next.yml 覆盖主题配置(Hexo 5+ 支持独立主题配置文件,不修改 node_modules 内文件)。
三、功能配置
3.1 本地搜索
npm install hexo-generator-searchdb |
_config.yml:
search: |
_config.next.yml:
local_search: |
format: striptags比html更干净,避免搜索结果中夹杂 HTML 标签。
3.2 RSS 订阅
npm install hexo-generator-feed |
_config.yml:
feed: |
3.3 深色模式手动切换
NexT 的 darkmode 默认跟随系统,但无法手动切换。通过自定义 CSS + 注入脚本实现:
source/_data/styles.styl — 定义深色变量和过渡动画:
:root { |
source/_data/body-end.njk — 在 </body> 前注入切换按钮和逻辑:
<button id="theme-toggle" aria-label="切换深色模式">🌙</button> |
3.4 中文界面 & 站点信息
_config.yml:
language: zh-CN |
3.5 社交链接
_config.next.yml:
social: |
四、部署到 Cloudflare Pages
4.1 推送到 GitHub
git remote add origin git@github.com:<your-name>/tiny-blog.git |
4.2 创建 Pages 项目
- Cloudflare Dashboard → Workers & Pages → 创建 → Pages → 连接到 Git
- 授权并选中仓库
4.3 构建配置
| 配置项 | 值 |
|---|---|
| Framework preset | None |
| Build command | npm install --no-fund --no-audit && npx hexo generate |
| Build output directory | public |
| Root directory | (留空) |
4.4 环境变量
在 Settings → Variables and Secrets 中添加:
| 变量名 | 值 | 说明 |
|---|---|---|
NODE_VERSION |
22 |
指定 Node 版本,与本地一致 |
五、踩坑:npm ci “Exit handler never called!” Bug
问题现象
Cloudflare Pages 构建日志报错:
npm error Exit handler never called! |
构建失败,无法部署。
根因
Cloudflare Pages 检测到仓库中存在 package-lock.json 时,会自动执行 npm ci 而非 npm install。npm ci 在 Node 22 + npm 10.x 组合下存在已知 bug(npm/cli#8404),会触发上述错误。
排查过程
尝试一:重新生成 package-lock.json + 添加 engines 字段
rm package-lock.json && npm install |
同时在 package.json 添加:
"engines": { "node": ">=18" } |
结果:仍然失败。npm ci 本身有 bug,版本声明无法绕过。
尝试二:添加 build:ci 脚本,设置 SKIP_DEPENDENCIES_INSTALL=true
在 package.json 添加:
"scripts": { |
Build command 改为 npm run build:ci,并设置环境变量 SKIP_DEPENDENCIES_INSTALL=true 跳过 Cloudflare 的自动安装步骤。
结果:仍然失败。Cloudflare 的环境变量文档不明确,行为不一致。
最终方案:将 package-lock.json 加入 .gitignore
package-lock.json |
不提交 lockfile → Cloudflare 检测不到 lockfile → 不触发 npm ci → 回退到 npm install → 构建成功。
Build command 最终定为:
npm install --no-fund --no-audit && npx hexo generate |
--no-fund --no-audit 减少无关日志输出,加速构建。
六、自定义域名
- Pages 项目 → 自定义域 → 设置自定义域
- 输入域名(如
blog.searchdiff.com) - 若域名 DNS 已托管在 Cloudflare → 自动添加 CNAME;否则手动在域名商处添加:
blog CNAME <your-project>.pages.dev
- 等待几分钟证书签发,HTTPS 自动生效
七、日常发布流程
本地写完文章后:
git add -A && git commit -m "new post: 文章标题" && git push |
Cloudflare Pages 自动拉取、构建、发布,约 1-2 分钟上线。
常用命令
hexo new "文章标题" # 新建文章 |
总结
Hexo + NexT + Cloudflare Pages 是一套低成本、高可用的静态博客方案。主要坑点是 Cloudflare 的 npm ci 自动行为与 npm 10 的兼容性问题——移除 package-lock.json 是最简洁的绕过方式。