用AI手搓一个Blog

my-edge-blog 项目文档

概览

一个部署在 Cloudflare Workers 上的个人博客系统,纯服务端渲染(SSR),支持多主题切换、管理后台、Markdown 渲染、暗色模式等。共 5,495 行代码。


技术栈

层级 技术
框架 Hono v4 — 轻量 Web 框架,JSX 模板引擎
运行时 Cloudflare Workers — 边缘计算平台
数据库 Cloudflare D1 (SQLite) — 文章/设置存储
对象存储 Cloudflare R2 — 图片上传和管理
KV Cloudflare KV — Admin Session 持久化
Markdown marked + marked-highlight + highlight.js
部署 Wrangler CLI
类型 TypeScript (JSX: react-jsx + hono/jsx)
CSS 原生 CSS + CSS 变量实现主题/暗色

完整功能清单

前端(4 套主题)

功能 说明
4 套独立主题 LoveIt (详细), PaperMod (简洁), Minimal (衬线留白), Tech (深色科技)
首页文章卡片 分页展示,支持置顶帖子
文章详情页 标题/日期/分类/标签/阅读时间/字数统计/浏览计数
Markdown 渲染 语法高亮 (highlight.js)、代码复制按钮、TOC 标题锚点
侧边栏目录 (TOC) 文章页左侧可折叠目录,手机端浮动按钮
搜索功能 全文搜索 + 关键词高亮 + 摘要回退
标签系统 标签列表页、按标签筛选
分类系统 分类列表页、按分类筛选
归档页 按年月分组,显示文章计数
关于页 Markdown 编辑器的自由内容
暗色模式 localStorage 持久化 + 系统偏好检测,图片暗调
阅读进度条 顶部彩色进度条
分享按钮 微博 / X (Twitter) 一键分享
上一篇/下一篇导航 文章底部相邻文章链接
RSS 订阅 /feed.xml 含全文 <content:encoded>
Sitemap /sitemap.xml 含分页、lastmod
robots.txt 动态生成,含正确域名 Sitemap URL
JSON-LD Schema.org Article 类型结构化数据
Open Graph OG title/description/url/image/type/site_name, article:published_time/modified_time, robots, Twitter cards
访问者统计 浏览量计数
无障碍 ARIA 标签、:focus-visible 全局样式、:prefers-reduced-motion、::selection 样式
无 404 破损 图片 onerror 隐藏、搜索内容为空回退

管理后台

功能 说明
Session 认证 KV 持久化 session + HttpOnly cookie
登录速率限制 5 次/5 分钟,基于 IP
文章 CRUD 新建/编辑/删除/批量删除
Markdown 编辑器 工具栏、分屏预览、拖拽上传、字数+阅读时间统计
主题切换 4 套主题一键切换
站点设置 标题/描述/页脚/GitHub/邮箱/头像/RSS 标题等
图片上传 R2 5MB 限制 + 类型白名单 + 速率限制 (20次/60秒)
置顶帖子管理 添加/移除置顶,排序
社交链接管理 添加/编辑/删除
关于页编辑 Markdown 编辑器
数据导出 JSON 格式导出所有内容

安全措施

措施 实现
XSS 防护 所有用户输入经 e() HTML 实体转义
安全头 X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy
CORS 控制 仅允许 github.io / localhost / 127.0.0.1
上传校验 文件类型白名单 + 大小限制
路径穿越 /assets/* 过滤 .. / / / \0
CDN SRI highlight.js 加载带 integrity + crossorigin
认证 KV session + HttpOnly + SameSite=Lax + Secure cookie

数据库表结构

-- 文章表
posts (id, slug, title, summary, content, cover_image, tags, category,
       published, created_at, updated_at, view_count)

-- 评论表(已建表,待开发)
comments (id, post_id, author, content, created_at)

-- 置顶帖子
pinned_posts (id, post_id, sort_order, created_at)

-- 站点设置
settings (key, value)

-- 社交链接
social_links (id, label, url, icon, sort_order, created_at)

源码结构

my-edge-blog/
├── src/
│   ├── index.ts        (143行) 入口、认证路由、安全中间件
│   ├── routes.ts       (273行) 公开路由(首页/文章/搜索/RSS/sitemap/robots)
│   ├── admin.ts        (310行) 管理后台 CRUD + 主题/设置/上传
│   ├── db.ts           (392行) D1 查询封装 + 内存缓存层
│   ├── auth.ts         (19行) 共享认证模块
│   ├── marked.ts       (46行) Marked 配置 + 自定义渲染器
│   └── templates.tsx   (2147行) 所有 JSX 模板(4主题 Layout + Page)
├── public/
│   ├── common.css      (577行) 共享样式
│   ├── theme-loveit.css     (451行)
│   ├── theme-papermod.css   (354行)
│   ├── theme-minimal.css    (345行)
│   ├── theme-tech.css       (438行)
│   └── robots.txt
├── migrations/ (6 个 SQL 迁移文件)
├── schema.sql          (完整建表 SQL)
├── wrangler.jsonc      (Cloudflare Workers 配置)
├── tsconfig.json       (TypeScript 配置)
└── package.json        (依赖配置)

路由表

路由 方法 功能
GET / public 首页(第1页)
GET /page/:page public 分页
GET /post/:slug public 文章详情
GET /tags public 标签列表
GET /tag/:tag public 按标签筛选(分页)
GET /category/:category public 按分类筛选(分页)
GET /about public 关于页
GET /search?q= public 搜索
GET /archives public 归档页
GET /feed.xml public RSS
GET /sitemap.xml public Sitemap
GET /robots.txt public Robots
GET /assets/* public R2 图片代理
GET /admin auth 后台首页
GET /admin/login auth 登录页
POST /admin/login auth 登录提交
POST /admin/logout auth 登出
GET/POST /admin/new auth 新建文章
GET/POST /admin/edit/:id auth 编辑文章
POST /admin/delete/:id auth 删除文章
POST /admin/bulk-delete auth 批量删除
POST /admin/upload auth 图片上传
GET/POST /admin/theme auth 主题管理
GET/POST /admin/pinned auth 置顶管理
GET/POST /admin/settings auth 站点设置
GET/POST /admin/about auth 关于页编辑
GET/POST /admin/social auth 社交链接管理
GET /admin/export auth 数据导出

部署文档(从头手搓)

前置条件

# 1. 安装 Node.js 18+
# 2. 安装 Wrangler CLI
npm install -g wrangler
# 3. 登录 Cloudflare
wrangler login

项目初始化

# 1. 创建项目目录
mkdir my-edge-blog && cd my-edge-blog

# 2. 初始化项目
npm init -y
npm install hono marked marked-highlight highlight.js
npm install -D wrangler @types/node

# 3. 配置 tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "skipLibCheck": true,
    "lib": ["ESNext"]
  }
}

创建 Cloudflare 资源

# 1. 创建 D1 数据库
wrangler d1 create notion-d1

# 2. 创建 R2 存储桶
wrangler r2 bucket create notion-r2

# 3. 创建 KV namespace
wrangler kv:namespace create ADMIN_KV

# 4. 设置管理员密码
wrangler secret put ADMIN_PASSWORD

配置 wrangler.jsonc

d1_databasesr2_bucketskv_namespaces 中的 ID 替换为上一步创建的值。

数据库初始化

wrangler d1 execute notion-d1 --file schema.sql
# 再依次执行所有 migrations/*.sql

本地开发

npm run dev
# 启动 http://localhost:8787
# 连接生产资源: npx wrangler dev --remote

部署

npm run deploy
# = wrangler deploy --minify

项目亮点

  • 零外部 Frontend 框架 — 纯 Hono JSX SSR
  • 零 CSS 框架 — 原生 CSS + 自定义属性
  • 全站 SSR — 首屏极速
  • 多主题架构 — 通过 Layout() 分发函数,新增主题只需加一个函数
  • 内存缓存层 — 60s TTL 减少 D1 查询次数
  • 边缘部署 — Cloudflare Workers 全球 300+ 节点

评论

评论功能即将上线,敬请期待。