这篇文章是本博客的第一篇正式文章。
它既用来记录这个博客从零开始搭建的过程,也作为以后更新、维护博客时可以随时查阅的一份操作说明。
整个博客目前采用的基本结构是:
1 | 本地 Hexo 源码 |
其中:
- Hexo 负责把 Markdown 文章生成静态网页;
- Git 负责记录源码的版本变化;
- GitHub 保存博客源码;
- Cloudflare Pages 从 GitHub 获取源码、执行构建,并把生成的网站发布到公网。
目前博客的公开地址为:
1 | https://wzgymgw-github-io.pages.dev |
一、博客诞生记录
1. 本地环境准备
博客最初使用 Windows 11 作为本地开发环境,并安装了:
- Git
- Node.js
- npm
- Git Bash
- Hexo
然后在本地建立 Hexo 项目。
Hexo 初始化后,项目中包含站点配置、文章目录、主题以及 Node.js 依赖配置等内容。
常用的几个基础命令包括:
1 | hexo s |
启动本地预览服务器。
1 | hexo new "文章标题" |
创建一篇新的博客文章。
1 | hexo clean |
删除 Hexo 的缓存数据库以及以前生成的 public 目录。
1 | hexo g |
或:
1 | hexo generate |
根据当前博客源码重新生成静态网页。
生成结果默认位于:
1 | public/ |
目录中。
2. Git 与 GitHub
为了对博客源码进行版本管理,本地 Hexo 项目本身被作为一个 Git 仓库管理。
博客对应的 GitHub 仓库为:
1 | wzgymgw/wzgymgw.github.io |
本地仓库通过 SSH 与 GitHub 连接。
SSH,即 Secure Shell,在这里主要用于让本地 Git 可以安全地向 GitHub 推送代码,而不需要每次重新输入账号密码。
SSH 配置完成后,可以通过:
1 | ssh -T git@github.com |
检查本机与 GitHub 的 SSH 连接。
当前仓库主要存在两个与博客有关的分支:
1 | master |
其中:
1 | master |
保存完整的 Hexo 源码,包括:
_config.ymlsource/package.jsonpackage-lock.json- 主题配置
- Markdown 文章
而:
1 | gh-pages |
曾用于保存 Hexo 编译完成后的 HTML、CSS、JavaScript 等静态网页文件。
3. Hexo 的 Git 部署能力
为了让 Hexo 可以把生成结果直接推送到 GitHub,安装了:
1 | hexo-deployer-git |
因此 package.json 中增加了:
1 | "hexo-deployer-git": "^4.0.0" |
同时 _config.yml 中配置:
1 | deploy: |
这样可以使用:
1 | hexo d |
把 Hexo 生成的静态文件推送到 gh-pages。
不过,在目前使用 Cloudflare Pages 的部署方案中,日常更新已经**不需要依赖 hexo d**。
Cloudflare 会直接读取 master 中的 Hexo 源码并自行构建。
因此 gh-pages 可以暂时保留,作为之前部署方式的记录或备用方案。
4. Cloudflare 初期踩坑
最初尝试把 GitHub 仓库连接到 Cloudflare。
为了保护其他私人仓库,在 GitHub 授权 Cloudflare Workers and Pages 时,只授权了当前博客仓库,而不是整个 GitHub 账号下的全部仓库。
最开始遇到的主要问题是:
Cloudflare 的新版创建界面默认更偏向 Workers,通过普通的 Continue with GitHub 入口进入后,会出现要求填写:
1 | Deploy command |
的 Workers 构建配置。
这与我要搭建的普通 Hexo 静态网站并不完全匹配,因此一度卡在这里。
后来重新进入 Cloudflare 后,在页面底部找到了:
1 | Continue to Pages |
并进入传统的 Cloudflare Pages Git 部署流程。
这才是当前博客实际采用的方案。
5. Cloudflare Pages 正式配置
Cloudflare Pages 连接的 GitHub 仓库为:
1 | wzgymgw/wzgymgw.github.io |
生产分支设置为:
1 | master |
由于 Cloudflare 的 Framework preset 中没有 Hexo,因此保持:
1 | Framework preset: None |
构建命令填写:
1 | npm run build |
构建输出目录填写:
1 | public |
这是因为 package.json 中存在:
1 | "scripts": { |
所以:
1 | npm run build |
实际等价于:
1 | hexo generate |
Cloudflare 的完整工作过程可以理解为:
1 | 拉取 GitHub master |
第一次部署时,Cloudflare 构建日志中成功完成:
1 | Cloning repository |
至此,博客第一次正式通过 Cloudflare Pages 上线。
二、博客基础信息配置
Hexo 默认创建的博客包含很多示例配置,例如:
1 | title: Hexo |
其中 John Doe 是英语环境中常见的示例姓名,并不是某个真实博客作者。
目前这些基础信息已经改为适合本博客的内容。
例如:
1 | title: WZGYMGW's blogs |
同时还设置了自定义的:
1 | subtitle: |
1. 关于 hexo config
修改配置时曾经使用过:
1 | hexo config title ... |
1 | hexo config author ... |
等命令。
这些命令确实可以修改 Hexo 配置,但实际使用后发现:
Hexo 会重新序列化整个 _config.yml 文件。
结果包括:
- 原来的大量官方注释被删除;
- 空值被改成
null; - 一些字符串被自动加引号;
- 原本没有修改的配置格式也发生变化。
虽然这些变化未必会让博客出错,但会导致:
1 | git diff |
出现大量无意义的改动,而且还会丢失很多很有价值的官方配置说明。
因此最后采用的做法是:
1 | git restore _config.yml |
先把配置恢复到 Git 中的正常版本,然后直接使用 VS Code 手动修改需要修改的几行。
以后修改 _config.yml 时,也优先使用这种方式。
三、第一篇文章与一次 404 排查
Hexo 初始化后会自动附带:
1 | source/_posts/hello-world.md |
因此最初上线后,首页中显示的是默认的:
1 | Hello World |
正式开始使用博客后,通过:
1 | git rm source/_posts/hello-world.md |
删除了默认文章。
随后提交并推送:
1 | git commit |
Cloudflare 也正常检测到了新的提交并进行了新一轮自动部署。
但是访问这一次部署对应的页面时出现了:
1 | 404 |
于是开始排查。
首先在本地执行:
1 | npm run clean |
清除:
1 | db.json |
然后重新执行:
1 | npm run build |
最终发现:
在博客中一篇文章都没有的情况下,这次 Hexo 构建只生成了 CSS、JavaScript、图片等静态资源:
1 | css/style.css |
但是没有生成:
1 | public/index.html |
因此 Cloudflare 虽然成功完成了“部署”,但部署产物中不存在网站首页,访问根路径自然得到 404。
这也是一个很重要的经验:
“Cloudflare 部署成功”只表示上传和发布流程本身成功,并不一定意味着网站内容本身一定正确。
因此除了看部署状态,还应该真正打开网站检查页面。
为了解决没有文章的问题,随后创建了本博客的第一篇正式文章:
1 | hexo new "博客搭建记录" |
也就是当前正在阅读的这篇文章。
四、博客搭建与维护操作
这一部分记录以后维护博客时经常会使用到的知识和命令。
1. Hexo 项目的几个重要位置
博客根目录中常见的重要内容包括:
1 | _config.yml |
其中:
_config.yml
Hexo 整个站点的主配置文件。
包括:
- 博客名称
- 作者
- 描述
- 语言
- 时区
- 网站地址
- 文章链接规则
- 主题
- 部署方式
source/_posts/
正式博客文章所在目录。
每一篇文章通常都是一个 Markdown 文件,例如:
1 | source/_posts/博客搭建记录.md |
public/
Hexo 构建生成的最终静态网站。
它不是平时主要编辑的源码目录,而是:
1 | Markdown + 配置 + 主题 |
的结果。
在当前 Cloudflare Pages 方案中,public/ 由 Cloudflare 自动生成和部署,因此一般不需要手动提交到 master。
package.json
Node.js 项目的配置与依赖文件。
目前其中最重要的脚本包括:
1 | "build": "hexo generate", |
因此:
1 | npm run build |
等价于:
1 | hexo generate |
2. 创建新文章
推荐使用:
1 | hexo new "文章标题" |
例如:
1 | hexo new "博客搭建记录" |
Hexo 会自动在:
1 | source/_posts/ |
中创建 Markdown 文件,同时自动生成文章的 Front Matter。
Front Matter(前置元数据) 是文章开头由 --- 包围的一段配置,例如:
1 |
|
它用于告诉 Hexo:
- 文章标题
- 发布时间
- 标签
- 分类
- 其他元信息
正文写在第二个:
1 | --- |
之后。
3. 编辑文章
创建文章以后,可以直接通过 Windows 文件资源管理器找到:
1 | source/_posts/ |
中的 Markdown 文件,再使用 VS Code 编辑。
也可以在 Git Bash 中执行:
1 | code "source/_posts/文章名.md" |
两种方式打开的是同一个文件。
因此,并不是所有操作都必须使用命令行。
比较适合直接使用图形界面的操作包括:
- 编辑 Markdown 内容;
- 查看文件;
- 浏览文件夹;
- 普通文件重命名;
- 修改
_config.yml。
比较适合使用命令行的操作包括:
- Hexo 创建文章;
- Hexo 本地服务器;
- Hexo 构建;
- Git 状态检查;
- Git 提交;
- Git 推送;
- 排查部署问题。
4. 本地预览
修改文章后,在正式上传之前,先执行:
1 | hexo s |
然后访问:
1 | http://localhost:4000/ |
检查:
- 首页是否正常;
- 文章是否正常;
- Markdown 是否正确渲染;
- 图片是否正常;
- 链接是否正常;
- 标题和排版是否满意。
预览完成以后,在运行 hexo s 的终端中使用:
1 | Ctrl + C |
停止本地服务器。
5. 清理与重新构建
平时不一定每次都需要清理。
普通构建可以:
1 | npm run build |
如果怀疑存在旧缓存或旧生成文件,可以先:
1 | npm run clean |
再:
1 | npm run build |
也就是:
1 | 清除旧缓存 |
这在排查问题时尤其有用。
五、Git 操作说明
Git 是整个博客维护流程中非常重要的一部分。
可以把一次修改理解为几个阶段:
1 | 本地修改文件 |
1. 查看当前状态
1 | git status |
这是最常用、也最值得经常执行的命令之一。
它可以告诉我:
- 修改了哪些文件;
- 哪些文件还没有暂存;
- 哪些文件已经准备提交;
- 当前所在分支;
- 本地与 GitHub 是否同步。
2. 查看具体修改
例如:
1 | git diff -- _config.yml |
可以比较 _config.yml 当前版本与 Git 中旧版本的差异。
在 git diff 中:
1 | 红色 / - |
表示旧内容或被删除的内容。
1 | 绿色 / + |
表示新的内容。
在正式提交之前先看一次 git diff,可以避免把意外修改提交进去。
3. 将修改加入暂存区
例如:
1 | git add _config.yml |
或者:
1 | git add "source/_posts/博客搭建记录.md" |
git add 只是告诉 Git:
这些修改准备进入下一次提交。
它还没有上传 GitHub。
相比直接使用:
1 | git add . |
在学习和维护阶段,我更倾向于明确写出文件名,这样更容易知道自己到底提交了什么。
4. 删除已经被 Git 管理的文件
例如删除默认文章时使用:
1 | git rm source/_posts/hello-world.md |
git rm 会同时:
1 | 删除文件 |
因此很适合删除已经被 Git 跟踪的文件。
5. 提交修改
例如:
1 | git commit -m "Update blog site configuration" |
提交后,这一次修改就成为 Git 历史中的一个正式版本。
一个好的 commit message 应该简短说明:
这一次到底做了什么。
例如:
1 | Configure Hexo Git deployment |
6. 推送到 GitHub
1 | git push origin master |
这一步才会真正把本地提交上传到 GitHub。
目前博客使用:
1 | master |
作为源码和 Cloudflare Production branch。
7. Git 的“日志”
Git 不会自动保存我每一次尚未提交的编辑操作。
真正进入 Git 历史的是:
1 | commit |
因此每次合理地进行 git commit 非常重要。
可以通过:
1 | git log --oneline |
查看简洁的提交历史。
例如可以看到:
1 | b32f4cd Remove default Hello World post |
这些提交记录本身就是博客源码的维护日志。
六、Cloudflare Pages 的作用
当前 Cloudflare Pages 与 GitHub 的:
1 | master |
分支连接。
以后每当执行:
1 | git push origin master |
Cloudflare 就会自动检测新的 commit。
然后执行:
1 | 拉取代码 |
因此日常更新博客时,不需要手动上传 public,也不需要每次都执行:
1 | hexo d |
1. Cloudflare 部署记录
Cloudflare 会自动保存每一次 deployment。
其中可以看到:
- 对应 Git 分支;
- commit ID;
- commit message;
- 部署时间;
- 构建状态;
- 构建日志;
- 本次部署对应的独立地址。
因此 Cloudflare 的 Deployment 记录与 Git commit 历史可以互相对应。
2. 构建日志
如果网站部署失败,或者 Cloudflare 显示成功但网页实际异常,可以进入:
1 | View build logs |
查看实际构建过程。
重点检查:
1 | Cloning repository |
以及是否出现:
1 | ERROR |
等信息。
七、以后更新博客的标准流程
经过第一次搭建以后,以后新增或修改文章的流程已经可以固定下来。
第一步:在本地新增或修改文章
新建文章可以:
1 | hexo new "文章标题" |
也可以直接修改:
1 | source/_posts/ |
中已有的 Markdown 文件。
第二步:本地预览
执行:
1 | hexo s |
然后访问:
1 | http://localhost:4000/ |
检查渲染效果。
确认没有问题以后停止本地服务器。
第三步:检查 Git 状态
1 | git status |
确认到底修改了哪些文件。
如有必要,再使用:
1 | git diff |
检查具体改动。
第四步:加入暂存区
例如:
1 | git add "source/_posts/文章名.md" |
如果同时修改了多个明确文件,可以分别添加。
第五步:再次确认
1 | git status |
确认:
1 | Changes to be committed |
中只有真正想提交的内容。
第六步:提交
1 | git commit -m "简短说明这次修改" |
例如:
1 | git commit -m "Add blog setup notes" |
第七步:推送 GitHub
1 | git push origin master |
推送后,GitHub 的 master 更新。
第八步:检查 Cloudflare
进入 Cloudflare Pages 项目,确认新的 commit 出现在:
1 | Production deployments |
并且部署状态成功。
如果失败,则查看:
1 | View build logs |
第九步:检查真正的网站
最后打开:
1 | https://wzgymgw-github-io.pages.dev |
并刷新页面。
检查:
- 新文章是否出现;
- 旧文章修改是否生效;
- 页面样式是否正常;
- 文章链接是否正常。
只有这一步也确认成功,才能认为一次博客更新真正完成。
因此完整流程可以简化记忆为:
1 | 本地写文章 |
八、目前形成的维护原则
经过第一次搭建和实际排查问题以后,目前我准备遵循以下原则。
博客文章和源码只在本地
master源码中维护。修改文章以后先本地预览,不直接上传。
提交之前使用
git status和必要的git diff检查实际变化。尽量明确
git add哪些文件,而不是无脑使用git add .。每一次相对完整的修改都进行一次有意义的 commit。
Cloudflare 当前直接从
master构建,因此日常发布主要依靠git push origin master。Cloudflare 显示部署成功以后,还必须实际打开博客确认页面内容。
出现奇怪问题时,可以使用:
1 | npm run clean |
在本地进行一次干净构建,判断问题究竟来自 Hexo 本身还是 Cloudflare。
_config.yml优先直接用文本编辑器修改,不再使用会重写整个配置文件的hexo config key value方式进行大量配置修改。Git commit 历史和 Cloudflare deployment 历史共同构成这个博客的技术维护记录。
九、结语
这篇文章既是这个博客真正开始运行的时间点,也是以后维护它时可以回头查阅的一份说明书。
从最开始只知道“想用 Hexo、GitHub 和 Cloudflare 搭一个博客”,到最终真正理解:
1 | Markdown |
每一层分别负责什么,这个博客才算真正从“一个能打开的网站”变成了“一个我知道如何维护的网站”。
以后无论是修改主题、增加分类与标签、加入图片、绑定自己的域名,还是继续完善自动部署,都可以在目前这套结构上逐步扩展。
而这篇《博客搭建记录》,就是这个博客的第一条正式记录。