第 5 章
一篇文章是怎么发出去的
博客搭好了、部署通了、服务器配好了,剩下的就是往里面填内容了。这一章讲的是现在写文章的完整流程——从打开编辑器到读者看到更新。
写
编辑器用的 Typora。文章格式是 MDX——Markdown 的超集,可以在文章里嵌入 React 组件(比如 ACA 合集里的刷题练习和记忆卡片),但日常写作跟写普通 Markdown 没有区别。
文件直接放在项目的 content/ 目录里,每个合集一个文件夹,每篇文章一个 .mdx 文件。想开一个新合集,建个目录、写一个 _meta.json 配置文件就行。
写作体验比之前好太多了。之前要打开浏览器、登后台、在网页编辑器里写,还不如 Typora 的所见即所得体验好。现在就是打开一个本地文件,写完保存,跟写笔记一样。
贴图
写文章免不了贴图。之前用完整前后端架构的时候,有个自建图床 API:粘贴截图 → 前端调 API → 后端存文件 → 返回 URL。后端砍掉之后这条路不通了。
8 月重建的时候,我设计过一个 SFTP 直传的方案:Typora 里粘贴截图,触发一个自定义脚本,把图片通过 SSH 传到服务器,再把公网 URL 返回给 Typora。脚本写好了,但服务器那头一直没真正接通——后来检查才发现,脚本要传的那个目录在服务器上根本不存在。
干脆换了思路:图片不上服务器了,跟文章一起放进仓库。截图直接放到 public/images/<合集>/ 里,文章里写 /images/... 引用,提交的时候图片和文章在同一个 commit 里,一起部署出去。这样图片跟着文章走,版本也跟着 git 走,服务器上少了一样要照看的东西,也不会再出现"文章发出去了、图片却打不开"的情况。
截图保持 PNG。终端截图大多是纯色背景加锐利的文字,PNG 无损压缩反而更小,我试过转成 WebP,有的体积还变大了一倍多。
封面
每个合集有一张封面图。这些封面是用 AI 画的——GPT Image 2,效果挺好。
画法大致是:先想好封面要表达什么(合集的主题、情绪),然后写一段 prompt 描述画面内容和风格,让 AI 生成。通常要调几轮——构图不满意就重新描述,细节不对就补充说明。
生成的原图(PNG,通常好几 MB)存在 assets/raw-images/ 目录里作为归档。发布之前跑一个优化脚本(npm run optimize-images),把 PNG 转成 WebP 格式,限宽 1600px,质量 82——肉眼看不出跟原图的差异,但文件大小能从几 MB 压到几十 KB。优化后的 WebP 文件输出到 public/images/,这才是最终部署到服务器上的版本。
原图留在仓库里,但不会被部署上去——Dockerfile 只复制 out/ 目录(构建产物),assets/ 不在里面。本地和 git 有归档,线上只有压缩后的小文件。
SVG 格式的图(比如架构图)不需要转换,直接放在 public/images/ 里就行。
发
写完、图片放好、封面做完,剩下的就是发布了。
git add .
git commit -m "feat: 新文章标题"
git push
push 到 master 之后 CI/CD 自动接管:构建静态站点 → 打包镜像 → 传到服务器 → 重启容器。几分钟后读者就能看到更新。
整个链路是:Typora 写内容 → 图片放进仓库 → git push → GitHub Actions 自动构建部署。中间没有后台、没有数据库、没有手动操作服务器。
以前改一篇文章的流程是:开浏览器 → 登后台 → 找到那篇文章 → 在网页编辑器里改 → 点保存 → 等接口返回。现在是:打开文件 → 改 → 保存 → git push。步骤少了一半,体验好了不止一倍。