EchoBlog

整理首屏资源

8%
EchoBlog
返回文章
前端开发

从原型到上线:EchoBlog 的内容与发布工程

复盘一个 Nuxt 个人博客如何把内容模型、全文搜索、SEO、资源策略和自动发布串成可维护的工作流。

从原型到上线:EchoBlog 的内容与发布工程

一个个人博客很容易从“做一个好看的首页”开始,也很容易停在这里。真正决定它能不能长期维护的,不是首屏用了多少动画,而是新增内容、发现内容、发布版本和处理故障时,是否都有清晰且可重复的路径。

EchoBlog 的目标因此逐渐从视觉原型变成一套完整工作流:内容使用 Markdown 管理,页面由 Nuxt 服务端渲染,搜索可以定位到正文标题,资源有 CDN 与同源回退,发布失败能够自动回滚,搜索引擎也能获得稳定的 canonical、sitemap 和结构化数据。

先定义内容事实,而不是先堆页面

文章和项目分别位于 content/articles/content/projects/。页面不再维护另一份静态列表,而是从 Nuxt Content 查询结构化 Frontmatter。这样,标题、标签、更新时间、封面和详情页始终来自同一份内容。

内容层还增加了三道约束:

  1. 标签和分类必须在 shared/taxonomy.ts 中登记,避免同义标签不断分裂。
  2. 草稿同时使用 draft: true.draft.md 文件名,生产构建会排除草稿文件。
  3. pnpm validate:content 在构建前检查 Frontmatter、分类、标签与发布占位语。

新内容可以从交互式命令开始:

Bashterminal
pnpm create:content

脚本默认创建草稿,生成稳定的 ASCII slug,并拒绝覆盖已有文件。作者完成正文和发布信息后,再显式切换为正式内容。这比直接复制旧 Markdown 更不容易留下错误字段。

一份索引服务多个入口

首页、文章页、项目页、标签页、归档页和近期足迹需要读取同一批内容,但它们的排序和筛选方式不同。项目将查询封装进 useArticleIndexuseProjectIndex,再由标签、归档和近期活动组合逻辑消费。

标签筛选采用交集语义。选择多个标签后,内容必须同时满足所有选中标签;没有结果时展示明确空状态,而不是留下空白区域。标签数量也从当前内容实时计算,不再使用样例数字。

近期足迹同样由文章 updated/date 与项目 updated/year 派生,避免首页维护一份很快过期的手写时间线。

搜索应当把人带到具体答案

只搜索标题对技术博客不够。EchoBlog 在服务端通过 Nuxt Content 的搜索段落数据构建索引,再使用 MiniSearch 完成相关度排序。中文文本由 Intl.Segmenter 分词,并补充单字和双字片段,兼顾短关键词与连续词组。

索引字段包含:

字段用途
标题最高权重,快速命中文章或项目主题
章节标题把结果定位到具体小节
标签与分类支持从概念词进入内容
正文覆盖真正的答案和实现细节

搜索结果保留章节锚点。用户按下回车后可以直接进入命中的小节,而不是只打开文章顶部。搜索弹层同时遵循组合框语义,支持方向键选择、Esc 关闭和焦点恢复。

SSR 页面也需要稳定的首屏数据

天气、访问统计和内容查询都可能在服务端与客户端之间切换状态。如果首屏 HTML 与水合时的客户端状态不同,就会出现闪烁或 hydration warning。

当前实现遵循两个原则:

  • 首次渲染使用服务端可确定的状态,客户端挂载后才进入需要浏览器能力的状态。
  • 外部接口失败时保留结构稳定的降级数据,不让整个页面因为一个卡片不可用而失败。

天气接口还按位置隔离缓存,访问统计用匿名哈希与会话窗口完成轻量 PV/UV 去重。它们适合当前单机个人站;只有在多实例或分析需求出现时,才值得迁移到数据库或独立统计服务。

资源策略从低带宽约束出发

图片源文件不会直接进入首屏。项目使用脚本生成限制尺寸与质量的 JPEG,音乐封面也有独立压缩流程。大体积音乐优先从静态域名加载,同源地址作为失败回退。

播放器没有在页面初始化时下载整份歌单。音频在用户播放时加载,封面和歌词按当前曲目切换。构建预算还会检查核心页面是否意外直接引用音频或 WASM,避免一次组件改动把首屏体积拉回去。

发布不是一条 SSH 命令

部署流程把质量门禁放在上传之前:

TEXT
内容校验 -> 单元测试 -> 类型检查 -> 生产构建
        -> 资源预算 -> 本地冒烟 -> SSH 发布
        -> 服务重启 -> 健康检查 -> 失败回滚

发布后,独立巡检任务会继续请求核心页面、动态内容路由、健康接口、sitemap、静态资源和 CDN 音频 Range。构建成功只能证明产物可以生成,生产巡检才能证明域名、反向代理、证书和资源服务仍然可用。

SEO 是内容模型的下游

每个页面的标题、描述、canonical 和 Open Graph 都从统一站点配置与内容元数据生成。文章和项目详情还输出 JSON-LD,sitemap 则直接遍历当前内容集合。

这意味着发布一篇新文章时,不需要手工修改 sitemap,也不应该在页面组件中重复填写标题。SEO 的可靠性来自内容模型的一致,而不是发布后的人工补丁。

下一步不是继续加功能

工程链路稳定后,最重要的事情变成持续写真实内容,并观察真实数据:

  • Search Console 是否抓取了预期页面,查询词是否与内容主题一致。
  • 生产巡检是否出现间歇性接口、证书或 CDN 故障。
  • 资源预算是否随着图片、音乐和组件增加而接近上限。
  • 哪些项目真正有演示和源码,哪些只是概念验证,页面是否诚实表达了状态。

个人博客不需要一开始就拥有评论、复杂 CMS、多作者权限和完整分析后台。先把写作、发布、发现和故障恢复做成可靠的日常流程,站点才有持续生长的基础。