博客主题对标后的六项核心改进记录
这次改造不是从视觉开始,而是先把博客和 Astro 官方 Themes 中几个成熟博客主题做了一次横向对标。对标报告放在 docs/ASTRO_OFFICIAL_BLOG_THEME_COMPARISON.md,样本包括 Retypeset、AstroPaper、Tone、Aonote、Chirping Astro 和 Basic Blog。
对标后能看出来:当前站点已经具备基础能力,优先要补的是生产质量、资源加载粒度、分享质量、全文搜索、技术写作体验和文章信息架构这几类低风险改进。因此这次只收敛到六项改动,没有把评论、i18n 或模板配置重构一起塞进来。
先处理生产质量问题
第一项是 CrashDetector。它本来是调试用组件,但文章布局会默认渲染它。调试组件进入生产页面会带来不必要的脚本、定时器和控制台输出,所以现在 src/layouts/BlogPost.astro 里通过 import.meta.env.DEV 控制,只在开发环境渲染。
这个改动的取舍很直接:调试能力保留,但不默认进入线上文章页。它符合 YAGNI,也避免让每篇文章都背上调试组件的运行成本。
第二项是 KaTeX 样式按需加载。之前 BaseHead.astro 静态引入 katex/dist/katex.min.css,即使非数学文章也会带上这份样式。现在 src/content.config.ts 增加了可选的 math frontmatter,src/layouts/BlogPost.astro 同时会检测正文中常见数学语法,再把结果作为 showKaTeX 传给 Layout 和 BaseHead。
也就是说,显式写 math: true 的文章会加载 KaTeX 样式;没有写时,布局会根据正文是否包含数学公式做兜底判断。这样不会要求每篇旧文章都立刻补字段,也能让普通文章保持更轻。
文章分享图回到文章级
BaseHead.astro 原本已经支持 image,但中间的 Layout.astro 没有把这个 prop 暴露出来,文章页也没有把 heroImage 传到 head。结果是文章详情页容易回退到默认分享图。
这次把链路补齐了:BlogPost.astro 将文章的 heroImage 传给 Layout.astro,再由 Layout.astro 传给 BaseHead.astro。无图文章仍然走默认 fallback,有图文章则可以在 Open Graph 和 Twitter Card 中使用自己的封面图。
这是一个小改动,但会影响文章被分享出去时的呈现。文章列表、详情页和分享卡片看到的主图不再脱节。
搜索从元数据扩展到正文
原来的搜索更像元数据搜索:标题、描述和标签能搜,但正文里的关键内容搜不到。对技术博客来说,这会明显降低可用性,因为很多检索动作其实是回忆某段实现、某个错误信息或某个配置项。
这次新增了 src/utils/searchText.ts,把 Markdown 正文清洗成适合索引的文本。它会去掉 frontmatter、代码块、图片、HTML 标签和大部分 Markdown 装饰,保留链接文本和行内代码文本。当前搜索正文最多保留 6000 个字符,摘要最多保留 220 个字符。
src/pages/search.json.ts 现在会输出 body 和 excerpt 字段,src/components/SearchModal.astro 则把 Fuse.js 的 keys 扩展为标题、描述、标签和正文。搜索结果展示时也会优先从命中的描述、摘要或正文里截取片段。
这次没有直接引入 Pagefind。原因是当前 Fuse.js 搜索链路已经存在,先在原链路上补正文索引,改动面更小,验证成本也更低。后续如果文章数量继续增长,再切到 Pagefind 会更有依据。
代码块体验补齐
代码块这次没有上 Expressive Code,而是在现有 Shiki 管线里做增强。核心点是保留代码块 meta:astro.config.mjs 里增加了 Shiki transformer,把原始 meta 写入 pre[data-meta]。
这里有一个实际踩坑:Shiki 当前上下文里可用的是 this.options.meta.__raw,不是一开始直觉上会找的 this.meta.__raw。只有拿到这段原始 meta,前端组件才知道标题、文件名和行高亮信息。
现在 src/components/CopyCodeButton.astro 不只负责复制,还会增强代码块展示:
- 显示代码语言;
- 支持
title或filename; - 支持
{1,3-5}这样的行高亮; - 对
diff代码块里的新增行和删除行做样式区分; - 避免 Astro 页面切换或动态内容导致重复初始化。
以后写文章时可以这样标注代码块:
```typescript title="demo.ts" {1,3-5}
const value = 1;
console.log(value);
```
这仍然是一个相对克制的实现。它没有引入新的 Markdown 组件体系,只是在现有代码高亮和复制按钮基础上补齐最常用的技术写作能力。
补上归档页
站点原来有首页、博客列表、标签页和 Blog Galaxy,但缺少一个按时间回看文章的低干扰入口。这次新增了 /archive,实现文件是 src/pages/archive.astro。
归档页复用 getSortedPublishedPosts(),按年份和月份聚合已发布文章。桌面导航和移动导航都在 src/components/Header.astro 中加入了“归档”,HeaderLink.astro 也补了 active 状态判断。
这类页面不复杂,但适合长期写作后的回看。标签页用于按主题找文章,归档页用于按时间查看项目变化,两者解决的问题不同。
验证结果
这次改造后已经跑过三类检查:
npm run type-check
npm run test
npm run build
结果如下:
| 检查项 | 结果 |
|---|---|
npm run type-check | 0 errors;仍有既有 hints/warnings |
npm run test | 1 个测试文件、6 个用例通过 |
npm run build | 168 pages built successfully |
产物层面也做了几项抽查:
| 抽查项 | 结果 |
|---|---|
/archive | dist/archive/index.html 存在 |
search.json | 包含 41 篇文章,且有 body 与 excerpt 字段 |
CrashDetector | 生产 HTML 没有引用该组件脚本 |
| KaTeX | 样式只出现在检测到数学内容或显式启用数学的页面 |
| 文章 OG 图 | 带 heroImage 的文章输出文章级 Open Graph/Twitter 图片 |
| 代码块 meta | pre 上可以看到 data-language 和 data-meta |
这次没有做什么
评论系统没有纳入这批修改。它确实是很多博客主题的常见能力,但对当前站点来说,评论涉及公开交互、审核和备案风险,默认接入线上不是低风险决策。后续更适合做成本地可验证、配置可开启、线上默认关闭的可选能力。
i18n 也没有做。当前内容主要面向中文读者,多语言路由会显著增加内容维护成本,不适合在这次质量修复里顺手展开。
最后,模板配置层也没有在这批改动里重构。站点级配置收敛值得做,但它会影响公开模板、README、同步脚本和部署说明,应该单独规划。
数据验证清单
| 文章声明 | 来源 | 状态 |
|---|---|---|
| 本次改造依据 Astro 官方博客主题对标报告 | docs/ASTRO_OFFICIAL_BLOG_THEME_COMPARISON.md | 已验证 |
CrashDetector 仅在开发环境渲染 | src/layouts/BlogPost.astro | 已验证 |
KaTeX 由 showKaTeX 按需输出 stylesheet | src/components/BaseHead.astro、src/layouts/BlogPost.astro | 已验证 |
博客 frontmatter 支持可选 math 字段 | src/content.config.ts | 已验证 |
文章 heroImage 会传给 Open Graph/Twitter meta | src/layouts/BlogPost.astro、src/layouts/Layout.astro、src/components/BaseHead.astro | 已验证 |
搜索索引包含正文 body 和摘要 excerpt | src/pages/search.json.ts、src/utils/searchText.ts | 已验证 |
| 搜索弹窗会检索正文并展示命中片段 | src/components/SearchModal.astro | 已验证 |
| 代码块支持语言、标题/文件名、行高亮和 diff 行样式 | astro.config.mjs、src/components/CopyCodeButton.astro | 已验证 |
新增 /archive 并按年月聚合文章 | src/pages/archive.astro | 已验证 |
| 导航已接入归档页并支持 active 状态 | src/components/Header.astro、src/components/HeaderLink.astro | 已验证 |
检查命令通过:type-check、test、build | 实际命令输出记录 | 已验证 |