首页归档标签关于
← 返回首页

把博客迁到 Astro:一次彻底的重写

#Astro#前端#折腾

上一次换主题是三年前,那时候用的是现成的 PHP 博客程序,改一行样式要刷新三次页面。这次索性推倒重来:静态生成、内容写在 Markdown 里、样式全部自己写。

为什么是 Astro

最直接的原因是默认零 JavaScript。博客这种内容型站点,95% 的页面只需要 HTML 和 CSS,可大多数框架会先丢一个几百 KB 的运行时过来,然后才开始渲染正文。

Astro 的做法相反:组件在构建期跑完,产出的就是纯 HTML。需要交互的地方,用 <script> 单独挂一小段 JS——我整个站点加起来不到 8 KB。

方案首屏 JS构建耗时心智负担
传统 SPA~180 KB快中
SSR 框架~60 KB中中
Astro 静态~8 KB快低

内容就是文件

内容用 Markdown 写,frontmatter 定义元信息:

---
title: 把博客迁到 Astro
date: 2026-10-26
tags: [Astro, 前端]
cover: /images/cover-1.svg
---

然后在 content.config.ts 里用 Zod 校验字段。写错一个字段名,构建直接报错——比在运行时悄悄渲染出空白页要好得多。

const posts = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/posts' }),
  schema: z.object({
    title: z.string(),
    date: z.coerce.date(),
    tags: z.array(z.string()).default([]),
  }),
});
静态生成的真正好处不是「快」,而是确定性。同一份输入永远产出同一份输出,出问题的时候可以本地复现。

为什么不用 Tailwind

这不是反对 Tailwind,它在团队协作里确实高效。但这个站只有我一个人维护,而且我对想要的视觉效果有很具体的想法:Material Design 3 的色板、圆角梯度、两套主题下的阴影差异。

这些用工具类拼出来会变成一长串 shadow-[0_4px_12px_rgba(28,20,48,0.07)],改一次要全局搜索替换。写成 CSS 变量反而清爽:

:root {
  --surface: #ffffff;
  --outline: rgba(26, 24, 32, 0.09);
  --r-lg: 28px;
  --shadow-2: 0 4px 12px rgba(28, 20, 48, 0.07);
}

[data-theme='dark'] {
  --surface: #1a1720;
  --outline: rgba(236, 233, 243, 0.1);
}

切换主题只是改 document.documentElement.dataset.theme,所有颜色自动跟着变。颜色、圆角、阴影都是令牌,不是样式。

留下的三个坑

  1. 暗色模式闪白:主题必须在 <head> 里同步读取 localStorage,不能等 JS 加载完再做,否则会闪一下。
  2. 中文字体:不要指望网络字体,直接堆系统字体栈,PingFang SC 和 Microsoft YaHei 覆盖 99% 的情况。
  3. 图片尺寸:封面统一 16:9 并显式写 width/height,避免布局抖动。

接下来

还差评论区和 RSS,另外想把「此刻」卡片接到真实的接口上,而不是手写死数据。

慢一点没关系,反正是自己的地方。