Hugo 博客 维护了几年,一直想换一个更轻量的方案。最近把博客从 Hugo Academic 迁移到了 Astro,记录一下过程。
为什么选 Astro
- 默认纯静态输出,零 JavaScript,性能极致
- 组件化架构,基于
.astro单文件组件 - 内置 Content Collections,类型安全的 Markdown
- 丰富的主题生态,AstroPaper 简洁专注
同类对比:Hugo 用 Go 模板,自定义灵活但学习曲线陡;Hexo 生态大但构建慢;Gatsby 依赖 React 太重。Astro 在静态博客场景下体验最好。
1. 初始化项目
npm create astro@latest -- --template satnaing/astro-paper .
注意:务必使用 pnpm 安装依赖,npm 会产生 vite/rolldown 类型冲突导致 astro check 失败。
rm -rf node_modules package-lock.json
pnpm install
模板拉下来后有大量演示内容,清理后只保留约 90 个必需文件。
最终的目录结构:
robin-homepage/
├── astro-paper.config.ts # 站点配置(一站式)
├── astro.config.ts # Astro 框架配置
├── package.json
├── deploy.js # 自定义部署脚本
├── public/ # favicon、OG 图片
└── src/
├── content/
│ ├── pages/about.md # 关于页面
│ └── posts/ # 博客文章 (.md)
├── components/ # 主题组件
├── layouts/ # 页面布局
├── pages/ # 路由
├── styles/ # 主题色、排版
└── utils/ # 工具函数
2. 配置站点
所有配置集中在 astro-paper.config.ts,一个文件搞定:
import { defineAstroPaperConfig } from "./src/types/config";
export default defineAstroPaperConfig({
site: {
url: "https://jianzhnie.github.io/",
title: "Robin's Blog",
description: "...",
author: "Robin",
lang: "zh",
timezone: "Asia/Shanghai",
},
posts: {
perPage: 5,
perIndex: 5,
},
features: {
lightAndDarkMode: true,
dynamicOgImage: true,
search: "pagefind",
},
socials: [
{ name: "github", url: "https://github.com/jianzhnie" },
{ name: "mail", url: "mailto:jianzhnie@gmail.com" },
],
});
注意:lang 设为 zh 后,必须同步在 astro.config.ts 中把 zh 加入 i18n.locales,否则 RSS 构建会报错 MissingLocaleError。
// astro.config.ts
i18n: {
locales: ["zh", "en"],
defaultLocale: "zh",
routing: { prefixDefaultLocale: false },
},
3. 撰写文章
文章放在 src/content/posts/,Markdown 格式的 frontmatter:
---
title: "文章标题"
author: "Robin"
pubDatetime: 2026-05-30T10:00:00Z
featured: false
draft: false
tags:
- tag1
- tag2
description: "文章摘要"
---
正文...
draft: true仅在pnpm dev可见,构建时自动排除- 支持子目录,如
tech/astro.md→ URL 为/posts/tech/astro/ featured: true在首页突出展示
4. 本地开发
pnpm dev # http://localhost:4321,支持热更新
pnpm build # 类型检查 + 构建 + Pagefind 搜索索引
pnpm preview # 预览生产构建
5. 部署到 GitHub Pages
不使用 GitHub Actions,而是本地构建后直接将 dist/ 推送到 GitHub Pages 仓库。
部署脚本 deploy.js 核心逻辑:
import { execSync } from "node:child_process";
const repoUrl = "https://github.com/jianzhnie/jianzhnie.github.io.git";
execSync(
`cd dist && git init && git checkout -b main && git add -A && git commit -m "deploy" && git push -f ${repoUrl} main`,
{ stdio: "inherit" }
);
执行:
pnpm deploy
流程:构建 dist/ → 在 dist/ 中初始化 Git → 强制推送到 jianzhnie.github.io 的 main 分支。
GitHub Pages 设置:Settings > Pages > Source = Deploy from a branch,选择 main 分支 / (root)。
6. 仓库管理
源码和部署分开两个仓库:
| 仓库 | 地址 | 内容 |
|---|---|---|
| 源码 | robin-homepage | Astro 项目、Markdown 文章 |
| 线上 | jianzhnie.github.io | 构建后的静态文件 |
日常工作流:
# 写文章、改配置
pnpm dev
# 备份源码
git add -A && git commit -m "..." && git push source main
# 部署上线
pnpm deploy
7. 迁移 Hugo 文章
从旧 Hugo 博客迁移 Markdown 文章,需要注意 frontmatter 格式差异:
| Hugo | AstroPaper |
|---|---|
date: '2022-10-22' | pubDatetime: 2022-10-22T00:00:00Z |
draft: false | draft: false (一致) |
tags: [a, b] | 列表格式,每行一个 |
| 无 slug | 文件名本身即 URL slug |
如果有 Hugo 源文件,直接把正文内容拷贝到 AstroPaper 的 frontmatter 下即可,格式兼容。
总结
从 Hugo 迁移到 Astro 的整体感受:开发体验更好(热更新快、TypeScript 类型安全),配置更集中,文章管理同样简单。如果你也在考虑换博客框架,Astro + AstroPaper 是一个值得推荐的选择。