- 原判断:半天搞定。实际:三个晚上,一半时间跟博客本身无关。
- 三个坑没有一个是技术难题,全是最开始的判断错了方向。
- 三次都先怪外部——缓存、网络、服务,最后发现是自己没看清。
- 真正要写的编辑器代码反而最顺,因为没引第三方库。
起因
前两篇讲了这个博客是什么、打算写什么。这篇讲它是怎么做出来的。
我原来的判断是:一个静态博客,本质就是一堆 Markdown 文件加一个模板,半天能搞定。结果花了三个晚上,其中一半时间在排查跟博客本身无关的事。
技术栈定了不到十分钟
| 项 | 选择 | 理由 |
|---|---|---|
| 框架 | VitePress | 文档全、配置短、不用写页面 |
| 托管 | GitHub Pages | 免费,还能挂 HTTPS |
| 发布 | GitHub Actions | 推上去自动构建,不用本地打包上传 |
选型没什么好纠结的。真正的麻烦在后面。
最后跑通的链路长这样
先把结果放这儿,下面三个坑都摔在这条链路上。注意虚线那一段:如果不是被坑过一晚上,不会有它。
第一个坑:文章列表全是空的
首页搭好,样式也调完了,打开一看——文章卡片是空的。框在,标题、日期、摘要一个都不显示。
第一反应是数据没加载出来,可能构建缓存的问题。清缓存,重启,还是一样。
第二步去看构建产物里的 HTML,发现卡片的结构是渲染出来的,链接也在,就是字段全空。
第三步才找到原因:我用了一个新版本才有的接口来读取文章信息,而这个版本的代码里根本没有这个参数。它不报错,也不警告,直接当没看见。
// docs/.vitepress/posts.data.mjs
export default createContentLoader('posts/*.md', {
transformData(raw) { /* 以为这样能读出文章信息,其实参数不存在 */ }
transform(raw) { /* 这个版本真正支持的写法 */ }
excerpt: true
})改成下面那种写法就好了。
不报错不等于成功了
有些失败是静默的,它只是安静地什么都不做。找这种问题,别从"哪里报错了"入手,要从"哪一步的结果是空的"往回倒推。
第二个坑:推送一直卡住不动
代码写完了要推到 GitHub。命令行敲下 push,光标转啊转,等了十分钟,一个字都没输出。
先怀疑是网络慢,重试了三次,都一样。
然后怀疑是仓库配错了,检查远程地址,没问题。
最后挨个测端口,发现环境变量里配了一个代理,那个代理是死的。所有走它的请求都被挂住。换成能用的那个,一秒就推上去了。
不过我的问题没那么快结束——换完之后虽然通了,但在命令行的沙箱环境里还是不稳。最后干脆换了条路:不用 git 命令推送,改成直接调 GitHub 的 API,把文件一个个建成提交传上去。
备用通路大概长什么样
# 编辑器里点"发布"时,先试常规推送;失败就自动切到这条
# 不依赖 git 命令,直接调 GitHub 的 API 建提交
python editor/api_push.py .这条路反而更可靠,后来就把它固化成了博客编辑器的发布方式。现在编辑器点"发布",先走常规推送,失败了自动切到 API,两条路都断才报错。
塞翁失马。如果不是被那个死代理坑了一晚上,也不会想到去做这条备用通路。
排查要一路排到最底层
"网络慢"是一个可以解释一切的答案,所以它最危险。把链路拆开,一段一段测,才会发现真正断掉的是中间那一小截。
第三个坑:按钮点了没反应
编辑器做出来之后,点"保存",屏幕上的状态提示一点变化都没有。
这次我的判断是:服务挂了。
于是查进程,活着。查端口,通着。查日志,没报错。反复重启,还是没反应。
折腾到后面顺手去看了一眼 git 记录,发现问题了——保存早就成功了,提交记录里明明白白躺着那一次修改。
真正坏的不是保存,是提示。我在页面脚本里用了 status 和 top 当变量名,这俩正好撞上浏览器内置的属性(一个是状态栏字符串,一个是窗口对象)。于是所有"已保存""发布中"的提示文字,都写到了一个没人看得见的字符串上。功能一直在正常工作,只是不吭声。
// editor/page.js
// 坏:status / top 是浏览器自带的,赋值不报错,但界面上看不到
status = '已保存'
top = '发布中'
// 好:换成普通变量名,再拿它去更新页面上的元素
const tipEl = document.getElementById('tip')
tipEl.textContent = '已保存'改掉变量名,加上出错弹窗,好了。
功能故障和反馈故障要分开看
先把"事情有没有做成"和"有没有提示我"拆成两件事,各自验证。我当时要是再多怀疑一会儿自己,可能就去改一堆本来没问题的代码了。
真正要写的部分反而最顺
编辑器本身没费什么劲——左右分栏写 Markdown、右边实时预览、一键发布,都没有引第三方库,纯标准库写的。
这么做的理由很直接:少一个依赖,少一处会崩的地方。 一个本地小工具,没必要为了省几行代码去装一堆包。
后来陆续加的左侧目录、搜索、暗色模式、归档页,也都很顺。真有问题的是往回看:这些功能本身不难,难的是搞明白前面那三个坑到底出在哪。
事后回头看
| 我一开始的判断 | 实际原因 | 教训 |
|---|---|---|
| 数据没加载出来 | 用了不存在的接口,静默失效 | 不报错不等于成功 |
| 网络太慢 | 环境里的代理是死的 | 排查要一路排到最底层 |
| 服务挂了 | 提示写错了地方,功能正常 | 功能故障和反馈故障要分开看 |
三次我都先怀疑了错误的方向。相同点是:第一反应都是怪外部(缓存、网络、服务),最后发现都是自己没看清。
下一步
先把文章稳定写下去。等攒够十篇左右,再考虑加评论区——现在加也没人评论,不急。