Hello World — 从零搭建个人博客的完整记录
这个网站上线了。这篇博文记录从零搭建的完整过程——技术栈怎么选、项目怎么搭、代码怎么写、怎么部署上线。即使你没碰过前端,也能跟着走一遍。
为什么要做个人网站
简而言之:想有一个属于自己的角落,不受平台限制,想写什么就写什么。
Vibe Coding:想法优先,技术其次
我不会前端开发,也不想学。这个网站完全是 Vibe Coding 出来的——告诉 AI 我想要什么,它帮我写代码。我只负责提想法、审结果、推上线。
但你还是需要知道这个网站用了什么技术,不是为了学它们,而是为了出问题时知道去哪里找答案。
建一个网站需要三样东西:写内容的工具、生成页面的框架、放上去让人访问的平台。
| 层级 | 技术 | 说明 |
|---|---|---|
| 内容层 | Markdown / MDX | 写文章就像写 Word 文档一样简单 |
| 框架层 | Astro 6 + Tailwind CSS 4 | 把 Markdown 变成漂亮的网页 |
| 部署层 | GitHub + Cloudflare Pages | 推送代码自动上线,免费且快 |
为什么选 Astro
市面上有很多建站框架,对比一下:
| 框架 | 适合场景 | 学习难度 | 特点 |
|---|---|---|---|
| Astro | 博客、文档、内容站 | 低 | 默认零 JS,速度极快 |
| Next.js | Web 应用、SaaS | 中 | 功能全面,但对博客来说太重 |
| Hugo | 博客、文档 | 中 | 速度极快,但模板语法难懂 |
| Hexo | 博客 | 低 | 老牌博客框架,但更新慢 |
Astro 核心优势:Islands Architecture — 整个页面默认纯 HTML,只有需要交互的部分(搜索框、主题切换)才加载少量 JS,页面加载速度极快。
为什么用 Tailwind CSS
Tailwind 是一个 CSS 框架,让你直接在 HTML 里写样式,不用另外写 CSS 文件:
<!-- 传统方式:写 HTML + 另一个 CSS 文件 -->
<div class="card">Hello</div>
<!-- .card { background: white; border-radius: 12px; padding: 16px; } -->
<!-- Tailwind 方式:直接在 HTML 里写 -->
<div class="bg-white rounded-xl p-4">Hello</div>
好处:不用在 HTML 和 CSS 文件之间来回跳转,改样式就在当前文件改。
为什么用 Cloudflare Pages
| 优势 | 说明 |
|---|---|
| 免费 | 每月 500 次构建,无限带宽,个人站绰绰有余 |
| 自动部署 | 推送到 GitHub 就自动构建上线,零操作 |
| 全球 CDN | 内容分发到全球节点,访问速度快 |
| 自定义域名 | 绑自己的域名,带免费 HTTPS 证书 |
项目结构
用 pnpm create astro@latest 初始化后,目录长这样:
src/
├── components/ # 可复用组件(导航栏、页脚、侧栏等)
├── content/ # 内容目录
│ └── blog/ # 博客文章(.md / .mdx 文件)
├── layouts/ # 页面布局模板
├── pages/ # 路由页面(文件路径 = URL)
│ ├── index.astro # 首页(访问 /)
│ ├── about.astro # 关于页(访问 /about)
│ └── blog/
│ ├── index.astro # 博客列表(访问 /blog)
│ └── [...slug].astro # 博客详情(访问 /blog/xxx)
├── styles/ # 全局样式
└── content.config.ts # 内容集合定义
关键概念:Astro 中 src/pages/ 下的文件路径直接映射为 URL。about.astro → /about,blog/index.astro → /blog。这叫”文件路由”,不需要手动配置。
内容管理:Content Collections
Astro 的 Content Collections 是管理博客文章的核心。你只需要在 src/content/blog/ 下创建 .md 或 .mdx 文件,写好 frontmatter(文件头部的元数据),Astro 就能自动读取和渲染。
一篇博文长这样:
---
title: "文章标题"
date: 2026-05-07
tags: ["标签1", "标签2"]
description: "文章简介"
image: "/images/cover.jpg" # 可选封面图
draft: false # true = 草稿,不会发布
---
这里是正文内容,用 Markdown 语法写。
然后在 src/content.config.ts 里定义集合的 schema(告诉 Astro 每个字段是什么类型):
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
schema: z.object({
title: z.string(), // 标题,必填
date: z.coerce.date(), // 日期,必填
tags: z.array(z.string()), // 标签数组
description: z.string().optional(), // 简介,可选
image: z.string().optional(), // 封面图,可选
draft: z.boolean().default(false), // 草稿,默认 false
}),
});
这样做的好处:类型安全、自动生成 TypeScript 类型、frontmatter 不合法时构建会报错。
组件化开发
Astro 组件(.astro 文件)是 HTML + JS 的混合体:
---
// 这里是组件逻辑(构建时运行)
const year = new Date().getFullYear();
---
<!-- 这里是模板(输出 HTML) -->
<footer>
<p>© {year} beautifugly</p>
</footer>
<style>
/* 这里是样式(自动 scoped,不影响其他组件) */
footer { text-align: center; padding: 2rem; }
</style>
这个网站拆成了这些组件:
| 组件 | 用途 |
|---|---|
Nav | 响应式导航栏,支持搜索 (Ctrl+K)、移动端菜单、主题切换 |
Footer | 页脚,显示版权和社交链接 |
Sidebar | 左侧固定信息卡,显示个人信息和技术栈 |
SEO | 生成 meta 标签、Open Graph、结构化数据 |
ThemeToggle | 暗色/亮色模式切换按钮 |
Newsletter | 邮件订阅表单组件 |
TOC | 文章目录,自动从标题生成 |
BackToTop | 滚动超过 300px 后显示的回到顶部按钮 |
所有页面共用一个 Layout(src/layouts/Layout.astro),它负责组装 Nav、Footer、SEO 等公共组件,页面只需要关注自己的内容。
设计系统
样式用 CSS 自定义属性(变量)统一管理,改一处全局生效:
:root {
--color-bg: #fbf9f8; /* 背景色 */
--color-bg-card: #f6f3f2; /* 卡片背景 */
--color-text: #1b1c1c; /* 主文本 */
--color-accent: #9f402d; /* 赤陶主色 */
--color-accent-secondary: #56642b; /* 鼠尾草绿 */
}
[data-theme="dark"] {
--color-bg: #1b1b1b; /* 暗色模式自动切换 */
--color-accent: #e2725b;
}
组件类(.btn-primary、.card、.chip)在 global.css 中定义,所有页面都能用。
部署到 Cloudflare Pages
第一步:创建 GitHub 仓库
先把项目代码放到 GitHub 上:
# 在项目根目录执行
git init
git add .
git commit -m "初始化项目"
git branch -M main
git remote add origin https://github.com/你的用户名/你的仓库名.git
git push -u origin main
没有 GitHub 账号?去 github.com 注册一个,免费的。然后点右上角 ”+” → “New repository” 创建仓库。
第二步:连接 Cloudflare Pages
| 步骤 | 操作 |
|---|---|
| 1 | 登录 dash.cloudflare.com,左侧菜单选 Workers & Pages |
| 2 | 点 Create → Pages → Connect to Git |
| 3 | 授权 Cloudflare 访问你的 GitHub,选择刚才创建的仓库 |
| 4 | 配置构建设置(见下表),然后点 Save and Deploy |
| 设置项 | 值 |
|---|---|
| Framework preset | Astro |
| Build command | pnpm build |
| Build output directory | dist |
| Node.js version | 18 或更高 |
注意:Cloudflare Pages 默认用 npm,但这个项目用 pnpm。需要在环境变量里设置 COREPACK_ENABLE=1,这样 Cloudflare 会自动识别 package.json 里的 packageManager 字段,用 pnpm 来安装依赖和构建。
点 Save and Deploy,等一两分钟,构建完成就能访问了。Cloudflare 会给你一个默认域名:你的项目名.pages.dev。
第三步:绑定自定义域名
如果想用自己的域名(比如 beautifugly.com):
| 步骤 | 操作 |
|---|---|
| 1 | 在 Cloudflare Pages 项目里点 Custom domains |
| 2 | 输入你的域名,Cloudflare 会自动配置 DNS 和 HTTPS 证书 |
| 3 | 域名在 Cloudflare 注册的,DNS 自动添加;否则手动加 CNAME 指向 xxx.pages.dev |
部署完成后的日常工作流
整个部署是全自动的,之后每次更新只需要:
# 写好文章或改完代码后
git add .
git commit -m "新增博文:xxx"
git push
# Cloudflare Pages 自动检测到推送
# → 执行 pnpm build
# → 生成 dist/ 目录
# → 部署到全球 CDN
# → 几秒后网站更新
整个过程不需要登录任何后台、不需要手动上传文件、不需要重启服务。写完推代码,网站自动更新。
接下来计划
希望这个小站能一直更新下去。