博客迁移至 Astro:从零搭建现代化个人站点

· 4382

为什么选择 Astro

Astro 是一个现代化的静态站点生成器,它的核心理念是 “Zero JavaScript by default”——默认情况下不向客户端发送任何 JavaScript,只在必要时按需加载。

与传统框架的对比

特性AstroNext.js / NuxtHexo / Hugo
默认 JS 体积0 KB~50-100 KB0 KB
组件化✅ 多框架支持✅ 单一框架❌ 模板引擎
Markdown 原生支持✅ 内容集合✅ MDX
构建速度快(Vite 驱动)中等
学习曲线
交互式组件按需 Island全量 Hydration需额外集成

核心优势

1. Islands Architecture(群岛架构)

Astro 的群岛架构让你可以在静态页面中嵌入交互式组件。每个交互组件都是一个独立的 “岛”,互不干扰:

---
// 静态部分 —— 构建时渲染,零 JS
---
<StaticHeader />
<!-- 交互式搜索 —— 仅在客户端加载 JS -->
<SearchModal client:load />
<!-- 只在可见时加载的评论组件 -->
<Comment client:visible />

2. 内容集合(Content Collections)

Astro 提供类型安全的内容管理,通过 Zod schema 定义 frontmatter:

// src/content.config.ts
const blogCollection = defineCollection({
  loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
    image: z.string().optional(),
    video: z.string().optional(),
  }),
});

3. 多框架兼容

同一个项目中可以混用 React、Vue、Svelte 组件,甚至纯 HTML/JS。


文章 Frontmatter 字段指南

每篇博客文章都是一个 Markdown(.md.mdx)文件,存放在 src/content/blog/ 目录下。文件头部使用 YAML frontmatter 定义元数据。

完整字段说明

---
title: 文章标题                    # 必填,显示在页面标题和列表中
description: 文章摘要              # 必填,用于 SEO description 和列表预览
pubDate: 2026-06-24               # 必填,发布日期
updatedDate: 2026-07-01           # 可选,最后更新日期
tags: [标签1, 标签2]               # 可选,标签数组,用于分类和筛选
draft: false                      # 可选,true 时仅在开发环境可见
image: https://example.com/img    # 可选,社交分享封面图
video: https://example.com/video  # 可选,视频链接
---

字段详解

title(必填)

文章标题,会显示在:

  • 博客首页文章卡片
  • 文章详情页顶部
  • 浏览器标签页标题
  • RSS 订阅标题
title: 一篇关于 Astro 的深度解析

description(必填)

文章的简短描述,用于:

  • SEO meta description
  • 文章列表卡片中的摘要文字
  • RSS 订阅摘要
  • 社交分享时的描述

建议控制在 120-160 字以内。

description: 本文深入探讨 Astro 的群岛架构及其在现代 Web 开发中的优势

pubDate(必填)

发布日期,决定文章在列表中的排序(按日期倒序)。支持 YYYY-MM-DD 格式。

pubDate: 2026-06-24

updatedDate(可选)

文章最后更新日期。设置后会在文章页面显示”更新于 xxx”,方便读者了解内容的时效性。

updatedDate: 2026-07-15

tags(可选)

标签数组,用于文章分类。标签会显示在:

  • 文章详情页标题下方
  • 文章卡片底部
  • /tags 标签聚合页
  • 每个标签的独立页面 /tags/[tag]
tags: [Astro, 前端, 博客]

draft(可选)

草稿标记,设为 true 后文章只在本地开发环境可见,生产构建时自动排除。默认为 false

draft: true  # 开发中,暂不发布

image(可选)

文章封面图 URL,用于 Open Graph 社交分享预览。

image: https://example.com/cover.png

video(可选)

文章关联视频链接。

video: https://www.youtube.com/watch?v=xxx

文件命名规范

推荐使用 YYYY-MM-DD-slug.md 格式:

src/content/blog/
├── 2026-06-24-astro-blog-migration.md
├── 2026-06-15-nas-setup.md
└── 2026-06-01-neovim-setup.md

这样既能在文件系统中按日期排序,也有语义化的 URL slug。


博客功能一览

本博客在迁移到 Astro 的过程中,逐步实现了以下特性:

内容与排版

  • Markdown / MDX 渲染 — 支持标准 Markdown 语法及 MDX 内嵌组件
  • 代码语法高亮 — 基于 Shiki,支持亮/暗双主题
  • 代码块一键复制 — 悬浮在代码块右上角的复制按钮
  • 自动目录(TOC) — 桌面端右侧固定目录,根据 h2/h3 标题自动生成

导航与浏览

  • 浮动快捷按钮 — 返回上一页、回到顶部、跳到底部
  • 文章分页 — 首页和归档页的分页浏览
  • 上一篇 / 下一篇导航 — 文章底部的前后文章跳转
  • 标签系统 — 标签云 + 标签聚合页 + 按标签筛选

搜索与发现

  • 全文搜索 — 基于 Pagefind 的静态搜索,构建时生成索引
  • RSS 订阅 — 自动生成 RSS 2.0 源
  • Open Graph 元数据 — 社交分享时的标题、描述、封面图

视觉与体验

  • 暗色 / 亮色主题 — 默认暗色,一键切换
  • 中英文双语 — 界面文字支持中文 / 英文切换
  • 响应式布局 — 桌面端三栏(个人信息 + 内容 + 目录),手机端自适应
  • 几何低多边形背景 — 装饰性背景图案
  • GitHub 贡献热力图 — 左侧信息栏集成 GitHub 活跃度

互动与社交

  • 评论系统 — 集成 Giscus(基于 GitHub Discussions)
  • 友链页面 — 支持头像、描述的好友链接展示
  • 个人信息卡片 — 头像、简介、社交链接

开发体验

  • TypeScript 支持 — 全链路类型安全
  • Vite 开发服务器 — 毫秒级热更新
  • 内容集合类型推断 — frontmatter 字段自动补全和校验
  • 草稿模式draft: true 仅在开发环境可见

快速上手:写一篇新文章

# 1. 在 src/content/blog/ 下创建新文件
touch src/content/blog/2026-06-24-my-post.md

# 2. 填写 frontmatter
# 3. 编写正文内容
# 4. 本地预览
npm run dev
# 5. 构建发布
npm run build

就这么简单——Astro 会自动识别新文件,生成对应的路由页面和 RSS 条目。


总结

Astro 的核心理念与个人博客场景天然契合:大部分内容都是静态的,只有少数几个交互组件需要 JavaScript。群岛架构让我们可以为每个交互组件精确控制加载时机(client:loadclient:visibleclient:idle),避免不必要的 JS 开销。

内容集合机制则让 Markdown 写作获得了类型安全保障——frontmatter 字段缺失或类型错误在构建时就能被发现,而不是发布后才发现页面显示异常。

如果你也在考虑博客框架选型,Astro 值得一试。