Article

个人博客重构记录:从 Zola 迁移到 Astro

前言

「佩璃的小屋」最早是用 Zola 搭的。刚开始只有几篇笔记的时候用着还挺省心,但随着我往博客里加了项目展示、截图图库、动态时间线和深浅主题,旧模板改起来越来越吃力。

10 月 12 日整理旧仓库的时候,我发现站里的几篇文章连头部配置(Front Matter)的写法都不统一:有的把分类、标签直接写在顶层,有的又包在 taxonomies 和 extra 里。如果模板少判断了一种写法,Markdown 看着好好的,生成的页面上却缺了封面或者分类。

与其继续在旧模板上打补丁,我干脆花时间把整个博客本地迁移到了 Astro,顺便把内容目录、字段规则和构建检查彻底理顺了一遍。

重要

迁移目标

  1. 坚持纯静态生成:不引后端数据库、不搞在线 CMS,也不为了几个按钮引入 React/Vue,关掉 JS 也能正常读文章看图。
  2. 统一内容结构:所有文章、项目和动态都用同一套扁平的顶层 YAML 字段,写错了在构建时直接报错提醒。
  3. 补齐全文搜索与自动检查:用 Pagefind 替换原来只搜摘要的旧搜索,并给链接、图片和草稿隔离加上自动化测试。

重构内容目录与字段规范

迁移当天,站里一共有 4 篇文章、5 个公开项目和 1 条草稿随记。我先把它们全部改成了按 ID 分目录存放的结构:

text
content/
├── articles/
│   └── wireguard-homelab/
│       ├── index.md
│       └── images/
├── projects/
│   └── my-blog/
│       └── index.md
└── activities/
    └── first-note/
        └── index.md

这样改有两个很实在的好处:

  1. 网址和标题解耦:文件夹名字(比如 wireguard-homelab)直接决定文章 URL,以后想改文章标题随时都能改,不怕链接失效。
  2. 图片跟着文章走:每篇文章的配图直接放在自己的 images/ 目录下,用 ./images/xxx.png 引用,再也不用像以前那样去全局 static/images/ 目录里翻来翻去了。

文章开头的 YAML 配置也全部拍平,不再套 extra 或 taxonomies:

yaml
---
title: 使用 WireGuard 远程访问家庭内网
published: "2026-05-24"
draft: false
category: HomeLab运维
tags: [Linux, WireGuard, VPN]
cover:
  src: ./images/wireguard.jpg
  alt: WireGuard 软件图标
---

依托 Astro 的 Content Collections 和自定义的检查脚本,现在只要字段名拼错、日期没加引号或者引用的本地图片不存在,运行检查命令时就会直接报错。迁移那天就靠这个抓出了旧 Neovim 文章里的一张失效封面引用。

统一内容发布与过滤规则

以前最怕出现一种尴尬情况:某篇草稿虽然没在首页列表里显示,但因为搜索索引或者 RSS 订阅源忘了加过滤,结果从侧门漏了出去。

这次迁移我把“判断一篇内容能不能公开”的逻辑统一收拢到了 src/lib/ 底下:

text
Markdown / YAML 源文件
       ↓ 字段与图片资源检查
统一的发布与排序规则(src/lib)
       ├── 页面列表与文章正文
       ├── Pagefind 搜索索引数据
       ├── RSS 订阅(feed.xml)
       └── 站点地图(sitemap.xml)

不管是文章、项目还是动态,日期统一按北京时间(UTC+8)解析。凡是标了 draft: true 或者发布日期在未来的内容,在正式构建(dist/)里一律过滤掉;哪怕某篇公开文章关联了一个还在写草稿的项目,正式页面上也不会把那个草稿项目的入口暴露出来。

平时自己在本地写草稿想看效果时,就用单独的 pnpm dev:drafts 或 pnpm build:drafts(输出到独立的 dist-drafts/ 目录),和正式发布的产物彻底分开。

源码结构与资源按需加载

新站点的代码结构按职责分得很清楚:

目录 / 文件作用
src/config、src/data站点基本信息、导航栏与分类预设
src/content.config.ts内容集合与 YAML 字段类型定义
src/lib发布过滤、排序、分类汇总、关联检查与 Markdown 处理
src/pages、src/layouts页面路由与布局模板
src/components独立 UI 组件
src/scripts浏览器端原生 JS 脚本
src/styles基础样式与各页面独立样式

以前旧站所有的交互都塞在一个全局脚本里,打开任何页面都要先跑一通 DOM 查询。现在改成组件脚本按需加载:只有文章里有 Mermaid 流程图或者打开了搜索框时,浏览器才会去请求对应的脚本;页面上的小图标也在构建阶段直接输出成内联 SVG,不用在浏览器里跑一套图标库。

接入 Pagefind 全文搜索

旧站的搜索只匹配截断后的文章摘要,经常搜不到正文里的命令或报错信息。迁移后我接入了 Pagefind,在 Astro 生成完静态 HTML 之后,直接扫描 dist 目录建立全文索引:

text
astro build
     ↓
生成静态 HTML 页面(dist/)
     ↓
pagefind --site dist
     ↓
生成按需加载的搜索索引分片

这样平时看文章的时候完全不加载搜索资源,只有点开搜索框时才会按需拉取索引。需要注意的一点是,因为索引是在 build 阶段生成的,平时跑 pnpm dev 改样式时没法直接测正式搜索,测搜索要先 pnpm build 再 pnpm preview。

图片渲染与标题层级处理

整理旧文章时还遇到了两个小问题:

  1. 旧文章正文里有很多一级标题 #:为了不用挨篇去改旧文章的 Markdown 源码,我在 Markdown 渲染插件里加了一步处理,自动把正文里的标题往下降一级,保证整个网页只有文章大标题自己是唯一的 <h1>。
  2. 不同比例的图片容易被裁坏:相机拍的照片、终端截图和宽屏界面比例差很多,如果强行居中裁剪很容易把边上的关键内容切掉。所以我做了一个通用的图片组件:前景完整显示原图,多出来的留白用同一张图片放大模糊后的背景铺底,看着自然又不会丢信息。

构建校验与维护流程

迁移完之后,每次改完代码或写完文章,跑下面这几条命令就能把类型、内容字段、单元测试和生成的 HTML 链接全检查一遍:

bash
pnpm check
pnpm test
pnpm build
pnpm build:drafts

旧的 Zola 源码我已经打包留了本地备份,以后就安心维护这套 Astro 源码了。现在写新文章不用再去猜字段怎么填,改页面也有测试兜底,比以前省心太多了。

个人博客重构记录:从 Zola 迁移到 Astro

https://www.renpengyu.com/articles/zola-to-astro/
作者
Penry
发布于
2026.10.12
许可协议
CC BY-NC-SA 4.0
站内搜索

找到你感兴趣的内容

文章分类
选择文章分类,匹配任意一个所选分类

多选时显示属于任一所选分类的文章。

文章标签
选择文章标签,多个标签需同时包含

多选时只显示同时包含所选标签的文章。

输入关键词开始搜索