从零搭建 Astro + Firefly 风格技术博客:完整指南
为什么选择 Astro?
在静态站点生成器(SSG)的选型上,我试用过 Next.js、Hugo、Hexo、VitePress 等多个方案,最终选择了 Astro,原因有三:
- 岛屿架构(Islands Architecture) — 默认零 JS,按需交互,性能极佳
- 内容优先 — 对 Markdown/MDX 的支持开箱即用,非常适合博客
- 生态丰富 — 官方集成了 Tailwind、MDX、Sitemap、RSS 等常用功能
而 Firefly 是我个人偏爱的一种设计风格——清爽的绿色主题、精致的卡片设计、舒适的阅读体验。本文就带你从零搭建一个 Firefly 风格的 Astro 博客。
一、项目初始化
1.1 创建 Astro 项目
# 方式一:使用官方 CLI(推荐)
npm create astro@latest my-blog
cd my-blog
# 方式二:手动搭建(更可控)
mkdir my-blog && cd my-blog
npm init -y
npm install astro @astrojs/tailwind @astrojs/mdx @astrojs/sitemap @astrojs/rss tailwindcss
1.2 基础配置
创建 astro.config.mjs:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';
import rss from '@astrojs/rss';
export default defineConfig({
site: 'https://your-blog.com',
integrations: [
mdx(),
sitemap(),
tailwind({ applyBaseStyles: false }),
],
markdown: {
shikiConfig: {
theme: 'github-dark-dimmed',
wrap: true,
},
},
});
1.3 Tailwind 配置
创建 tailwind.config.js,定义 Firefly 主色调:
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}'],
darkMode: 'class',
theme: {
extend: {
colors: {
firefly: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e', // 主色调
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d',
},
},
},
},
plugins: [],
};
二、目录结构设计
一个清晰的目录结构是博客可维护性的基础:
src/
├── components/ # 可复用组件
│ ├── Header.astro
│ ├── Footer.astro
│ ├── PostCard.astro
│ ├── PostHeader.astro
│ ├── ThemeToggle.astro
│ └── ...
├── layouts/ # 页面布局
│ ├── BaseLayout.astro
│ └── PostLayout.astro
├── pages/ # 路由页面
│ ├── index.astro # 首页
│ ├── about.astro # 关于页
│ ├── posts/ # 文章列表与详情
│ │ ├── index.astro
│ │ └── [...slug].astro
│ ├── categories/ # 分类页
│ └── tags/ # 标签页
├── content/ # 内容集合(Content Collections)
│ ├── config.ts
│ └── blog/
│ ├── post-1.md
│ └── post-2.md
├── lib/ # 工具函数
│ └── posts.ts
├── styles/ # 全局样式
│ └── global.css
└── config.ts # 站点配置
💡 Content Collections 是 Astro 的杀手级功能!它提供类型安全的内容管理,frontmatter 写错了会直接在构建时报错。
三、核心功能实现
3.1 深色模式
深色模式的关键是避免 FOUC(闪屏)——必须在页面渲染前就确定主题:
在 BaseLayout.astro 的 <head> 中加入:
<script is:inline>
(function () {
try {
const stored = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (stored === 'dark' || (!stored && prefersDark)) {
document.documentElement.classList.add('dark');
}
} catch (e) {}
})();
</script>
然后用 CSS 变量定义主题色,切换时只改变量:
:root {
--bg-primary: #ffffff;
--text-primary: #0f172a;
--accent-color: #22c55e;
}
.dark {
--bg-primary: #0f172a;
--text-primary: #f1f5f9;
--accent-color: #4ade80;
}
3.2 文章列表与分页
使用 Content Collections 获取文章:
import { getCollection } from 'astro:content';
import { sortPostsByDate } from '@lib/posts';
const posts = sortPostsByDate(await getCollection('blog'));
排序和过滤逻辑抽到 lib/posts.ts 中复用:
export function sortPostsByDate(posts: PostEntry[]): PostEntry[] {
return posts
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
}
3.3 分类与标签
分类和标签的实现思路一致:
- 遍历所有文章,用
Map统计各分类/标签的文章数 - 生成列表页(展示所有分类/标签)
- 用动态路由
[category].astro/[tag].astro生成详情页
核心统计函数:
export function getAllTags(posts: PostEntry[]): { name: string; count: number }[] {
const map = new Map<string, number>();
for (const post of posts) {
for (const tag of post.data.tags || []) {
map.set(tag, (map.get(tag) || 0) + 1);
}
}
return Array.from(map.entries())
.map(([name, count]) => ({ name, count }))
.sort((a, b) => b.count - a.count);
}
3.4 SEO 优化
不要忽视基础的 SEO:
- ✅
<title>和<meta description>— 每页独立设置 - ✅ Open Graph + Twitter Card — 社交分享预览
- ✅ Sitemap — 用
@astrojs/sitemap自动生成 - ✅ RSS — 用
@astrojs/rss生成订阅源 - ✅ 规范链接(canonical)— 避免重复内容
- ✅ 语义化 HTML —
<article>、<header>、<nav>该用就用
四、部署上线
Astro 生成的是纯静态站点,部署选项非常多:
| 平台 | 特点 | 适合场景 |
|---|---|---|
| Vercel | 一键部署、自动 CI、Edge Functions | 个人博客首选 |
| Netlify | 功能丰富、Forms、Edge Functions | 需要高级功能 |
| Cloudflare Pages | 全球 CDN、速度快 | 追求极致速度 |
| GitHub Pages | 免费、和仓库绑定 | 开源项目博客 |
| 自建服务器 | 完全可控 | 有服务器资源 |
以 Vercel 为例,只需三步:
# 1. 构建测试
npm run build
# 2. 本地预览
npm run preview
# 3. 推送到 Git 仓库,Vercel 自动部署
git push
五、优化建议
5.1 性能优化
- 🖼️ 图片使用
<Image>组件,自动优化格式和尺寸 - 📦 开启
prefetch预加载导航链接 - 🔤 字体使用
font-display: swap避免阻塞渲染 - 🎨 内联关键 CSS,减少 FOUC
5.2 写作体验优化
- ✍️ 用 MDX 支持在文章中插入组件
- 📅 草稿功能:
draft: true的文章不发布 - 🏷️ 精选文章标记:
featured: true在首页突出展示 - ⏰ 预计阅读时间:根据字数自动计算
5.3 监控与分析
- 📊 接入 Plausible / Umami 等轻量级统计
- 💬 添加评论系统(Giscus、Disqus、或自建)
- 📧 邮件订阅(Buttondown、Mailchimp)
小结
搭建一个博客的过程本身就是一次很好的学习机会——你会接触到前端工程化、SEO、性能优化、CI/CD 等方方面面。
但更重要的是:内容才是博客的核心。工具和外观只是载体,持续输出有价值的内容才是关键。
希望这篇文章对你有帮助。如果你有任何问题,欢迎在评论区交流~
下一篇预告:《Astro 博客进阶:MDX 组件与交互式内容》