git checkout logs

这个知识博客是如何构建的:技术架构与 UI 设计拆解

commitd31c9a2
Author:strtus
Date:2026-04-03 20:10:00

这个博客的目标:把知识管理做成一次次可追踪的提交

这个博客的设计出发点很明确:把“写作”抽象成“提交(commit)”,把“阅读”抽象成“浏览分支(branches)与历史(logs)”。

这不是视觉噱头,而是一个工程上的统一心智模型:

  1. 内容层是一组可版本化的 Markdown 文档。
  2. 数据层把每篇文档映射成统一的 Post 结构。
  3. 视图层提供两种投影:按时间看 history,按分支看 domain。

这三层对应后,功能扩展会非常稳定。

一、技术架构:轻后端、强约束、可静态化

1) 技术栈选择

  • 框架:Next.js App Router
  • 语言:TypeScript
  • 样式:Tailwind v4 + CSS 变量主题
  • 内容:本地 Markdown 文件
  • 渲染:ReactMarkdown + GFM + 数学公式(KaTeX)

核心原则是“内容优先、复杂度后置”:在还不需要数据库和 CMS 的阶段,用文件系统直读内容,换来更低维护成本与更高可移植性。

2) 内容管线:文件系统即内容数据库

所有文章存放在 content/posts,每篇文章使用 frontmatter 描述元信息:

---
id: "post-id"
title: "文章标题"
date: "2026-04-03 20:10:00"
author: "strtus"
branch: "architecture"
summary: "列表页摘要"
---

解析逻辑在服务端完成:

  • 读取目录下所有 .md
  • 解析 frontmatter 与正文
  • 标准化为 Post 类型
  • 按 date 倒序排序

这套流程的好处是:

  1. 数据结构固定,页面层几乎不需要防御式编程。
  2. 内容新增只需“新增文件”,不需要改代码。
  3. 具备天然的 Git 追踪能力。

3) 路由策略:基于 id 的稳定地址

详情页采用 /post/[id],并通过 generateStaticParams 预生成路由参数。这样做有两层收益:

  1. URL 稳定,不受标题变更影响。
  2. 可静态化输出,首屏开销低。

日志页与分支页本质是同一份数据的两种查询方式:

  • logs:时间维度
  • branches(路由保留为 /topics):领域维度

4) 搜索实现:参数驱动而非全局状态

搜索框把关键词写入 URL query(例如 /logs?q=xxx),列表页通过 useSearchParams 读取后在内存中过滤:

  1. 搜索条件可分享(复制链接即可复现)
  2. 与浏览器前进/后退行为天然一致
  3. 不需要额外状态管理库

在规模较小的知识博客里,这种策略的工程性价比很高。

二、Markdown 渲染:兼顾可读性与技术表达

文章页的正文渲染组合是:

  • remark-gfm:表格、任务列表等扩展语法
  • remark-math + rehype-katex:数学公式排版
  • rehype-slug:自动生成标题锚点

并且基于正文自动提取 H1-H3 生成目录树(Tree)。

这让文章可以同时承载两类内容:

  1. 面向工程实践的代码片段
  2. 面向理论分析的公式推导

对于技术博客,这是非常关键的一点。

三、UI 设计:把 Git 语义转成视觉语法

这个博客的 UI 不是“通用博客皮肤”,而是刻意向 Git 的信息结构靠拢。

1) 字体系统:三层职责分离

  • Sans(Inter):正文与主阅读区
  • Serif(Newsreader):强调性标题
  • Mono(JetBrains Mono):元信息、命令语义、时间戳

这是一种“信息分层”的字体策略:用户只靠字形就能判断内容类别。

2) 色彩系统:暖色纸面 + 单一强调色

主题色变量采用“纸面底色 + 低对比边框 + 橙色强调”的方案:

  • 背景不是纯白,而是轻暖底色
  • 文本主色偏深棕黑,减轻刺眼感
  • 强调色只在关键交互上出现(链接、节点、hover)

这样做可以降低视觉噪声,提升长文阅读舒适度。

3) 结构隐喻:时间线与分支树

  • Logs 页面用纵向时间线 + 节点圆点表达提交序列
  • 文章目录用树状连线表达标题层级
  • Branches 页面按 branch 分组,强化“知识分叉”概念

这些元素本质上是在把抽象的数据结构可视化。

4) 交互细节:克制动画与渐进展示

  • 列表项使用短时位移动画,改善信息进入节奏
  • 搜索输入采用展开/收起,默认保持页面简洁
  • 首页在桌面端仅保留 Logo,次级页面显示站点名,突出“首页入口感”

它们共同服务一个目标:让交互“有反馈但不抢戏”。

四、为什么这套方案可持续

从工程角度看,这个博客具备几个可长期迭代的特征:

  1. 内容与展示解耦:Markdown 可迁移,页面可重做。
  2. 数据模型稳定:Post 字段少而明确,重构成本低。
  3. 渲染链路可控:插件组合清晰,不依赖重型 CMS。
  4. UI 语义一致:视觉元素和信息架构互相解释。

如果后续要升级,可以沿以下方向演进:

  • 引入全文索引(如 MiniSearch)提升搜索规模上限
  • 增加阅读状态(最近阅读、关联文章)
  • 增加构建期校验(frontmatter schema 校验、死链检查)

结语

这个博客最重要的不是“用了哪些框架”,而是它把一个明确的认知模型贯彻到了实现细节:

  • 内容像提交一样可追踪
  • 结构像分支一样可分化
  • 界面像 Git 一样强调关系而非装饰

当技术架构与 UI 语义指向同一个目标时,系统就会同时具备可读性、可维护性和可扩展性。