个人博客技术优化笔记

这次优化的目标很明确:保留独立的本地博客 Markdown 文件夹,让服务器只负责托管最终渲染后的静态文件。博客内容、构建工具链、部署目标之间要边界清晰,避免以后因为路径分叉、重复构建、手工同步而返工。

原始问题

早期流程可以工作,但职责混在一起:

  • 本地有站点工程 caseshy-blog
  • 本地有独立内容库 博客markdown
  • 服务器上也保留了一份站点源码。
  • 服务器上还同步过一份 Markdown 内容库。
  • 发布时既可能在本地构建,也可能在服务器构建。

这带来一个典型问题:本地验收通过的内容,不一定就是服务器最终构建出来的内容。只要漏掉一次 git pushrsync 或服务器构建,线上状态就可能和本地认知不一致。

核心判断

个人静态博客不需要复杂发布系统。按照奥卡姆剃刀原则,优先删除不必要的路径,而不是增加新的协调机制。

最终选择是:

  • Markdown 内容只保存在本地独立文件夹。
  • 构建只在本地发生。
  • 检查只针对本地生成的 output/
  • 服务器只接收 output/ 里的 HTML、CSS、JS、图片和字体。
  • Nginx 只负责静态托管,不参与构建。

这让工作流从“多处状态协同”变成“本地生成一个确定产物,然后发布它”。

新流程

日常写作时,只管理本地内容库:

/Volumes/工作固态/AliBlog项目/博客markdown

站点工程只负责读取它:

/Volumes/工作固态/AliBlog项目/caseshy-blog

发布入口收敛为一个命令:

npm run publish

这个命令内部完成:

本地构建 -> 本地检查 -> 同步 output/ 到服务器 -> 修复静态文件权限 -> nginx 配置检查 -> reload nginx -> 线上 HTTP 验收

如果中间任一步失败,发布就停止。这样失败会尽早暴露,不会把半成品推到线上。

为什么不让服务器构建

服务器构建看起来省事,但会制造隐性耦合:

  • 服务器必须长期维护 Node、npm、cwebp、依赖缓存。
  • 本地和服务器的 Node 版本、系统环境可能不同。
  • 本地已经构建检查过,服务器再构建一次属于重复工作。
  • 服务器保留 Markdown 内容后,又多了一份需要同步和清理的状态。

静态博客的优势是最终产物简单。既然最终要上线的是静态文件,就应该只发布静态文件。

检查机制

新增的本地检查脚本负责挡住常见低级问题:

  • 忽略 .DS_Store._*.md 等系统文件。
  • 检查 Markdown 内容是否能生成对应 HTML。
  • 检查重复 slug。
  • 检查页面标题和描述。
  • 检查备案号和公安备案信息是否存在。
  • 检查静态资源引用是否存在。
  • 检查生成 HTML 中是否残留明显损坏的 Markdown 标记。

这些检查不是为了把项目变复杂,而是为了减少人工反复点页面、反复修小错的浪费。

设计和法规约束

页面设计继续沿用当前站点风格:克制、清晰、内容优先,配色保持暖底色、深文字、青绿色强调色。交互不引入重运行时逻辑,符合 HarmonyOS NEXT 强调的确定状态、声明式 UI、性能优先思路。

备案信息必须稳定展示:

  • 工信部备案号:陇ICP备2026004536号-1
  • 公安联网备案号:甘公网安备62010302001825号

这些信息在页脚展示,并链接到官方备案查询平台。发布检查会验证备案文本存在,避免模板调整时误删。

实际踩坑

第一次只同步 output/ 时,线上出现了 403。原因是 macOS 本地文件权限通过 rsync 保留到了服务器,导致 Nginx 无法读取目录。

修复方式不是手工改一次权限,而是把权限修复写进发布脚本:

chown -R root:root /var/www/caseshy-blog
find /var/www/caseshy-blog -type d -exec chmod 755 {} +
find /var/www/caseshy-blog -type f -exec chmod 644 {} +

这样以后每次发布都会得到可预期的服务器文件权限。

最终原则

这次优化遵守两条工程原则:

  • 高内聚:构建、检查、发布都集中在站点工程里。
  • 低耦合:博客 Markdown 内容库独立存在,服务器只接收静态产物。

最终流程足够简单:

写 Markdown
npm run publish
打开线上页面验收

对个人博客来说,这比引入远端仓库、CI/CD、服务器构建和多套同步脚本更可靠,也更容易长期维护。