最新需求文档 v1.3
一、项目定位
Chunking — 一个基于 GitHub Discussions 作为内容管理系统的纯前端博客平台。作者通过 GitHub Discussions 撰写和管理文章,访客通过博客站点阅读文章并留言评论。零后端、零数据库、零托管成本。
核心特征:构建时生成完整静态 HTML,运行时 Hydration 为 SPA,兼顾 SEO 与交互体验。
二、技术选型约束
| 层级 |
技术 |
版本/来源 |
约束说明 |
| 构建工具 |
Vite |
^5.0 |
开发服务器、模块打包、环境变量注入、构建时 SSG 触发 |
| 构建时数据获取 |
Octokit Core.js |
^6.0 |
仅在构建脚本中使用,运行时前端不直接调用 GitHub API |
| 运行时路由 |
原生 JS SPA Router |
参考 jsdev.space 实现 |
History API、动态路由参数、404 回退、Hydration 接管 |
| Markdown 渲染 |
Marked.js |
^12.0 |
构建时预渲染 + 运行时客户端渲染共用同一套逻辑 |
| 代码高亮 |
highlight.js |
^11.0 |
构建时与运行时共用 |
| 评论系统 |
Giscus |
最新 CDN |
Web Component 方式嵌入,通过 data-term 绑定 Discussion number |
| 样式 |
原生 CSS |
— |
CSS 变量定义设计系统,无预处理器 |
| 图标 |
内联 SVG / Phosphor Icons CDN |
— |
不引入图标字体 |
三、页面结构规范
3.1 共用布局
┌─────────────────────────────────────┐
│ Header │
│ [Logo: chunking] [Categories] [Tags] [About] │
├─────────────────────────────────────┤
│ Main Content (动态路由区域) │
├─────────────────────────────────────┤
│ Footer │
│ © 2026 Vanilla JS Development - All rights reserved │
└─────────────────────────────────────┘
3.2 路由表
| 路由 |
页面类型 |
布局内容 |
构建时输出 |
/ |
一级 |
文章列表 + 分页 |
dist/index.html |
/categories |
一级 |
分类卡片网格 |
dist/categories.html |
/categories/:slug |
二级 |
面包屑 + 分类统计 + 简介 + 文章列表 |
dist/categories/{slug}.html |
/tags |
一级 |
标签云/列表 |
dist/tags.html |
/tags/:slug |
二级 |
面包屑 + 标签统计 + 简介 + 文章列表 |
dist/tags/{slug}.html |
/about |
一级 |
博客简介 |
dist/about.html |
/posts/:id |
二级 |
面包屑 + 博文详情 + Giscus 评论 |
dist/posts/{id}.html |
3.3 面包屑规范
首页 > Categories > Astro (分类详情页)
首页 > Tags > Tailwind (标签详情页)
首页 > Posts > 文章标题 (文章详情页)
四、数据流规范
4.1 GitHub 数据模型映射
GitHub Discussions ←→ 博客文章
├── title ←→ 文章标题
├── body (Markdown) ←→ 文章内容
├── category ←→ 博客分类 (Categories)
├── labels ←→ 博客标签 (Tags)
├── createdAt ←→ 发布日期
├── updatedAt ←→ 更新日期
├── author ←→ 作者信息
├── number ←→ 文章 ID (用于路由)
└── comments ←→ 通过 Giscus 展示,不直接读取
4.2 特殊分类约定
| Discussion Category |
用途 |
是否展示在博客列表 |
Blog |
普通博客文章 |
✅ 是 |
About |
关于页面内容 |
❌ 否,仅用于 /about 路由 |
Draft |
草稿 |
❌ 否 |
4.3 构建时数据流
构建触发(CI 或手动)
│
▼
┌─────────────────┐
│ 1. 通过 Octokit │──── 一次性拉取全部 Discussions、Categories、Labels
│ 拉取 GitHub │
│ Discussions │
└─────────────────┘
│
▼
┌─────────────────┐
│ 2. 数据分类处理 │──── 过滤、分组、统计
│ & 内容渲染 │
└─────────────────┘
│
▼
┌─────────────────┐
│ 3. 生成静态 HTML │──── 每页独立 HTML 文件,含完整内容 + meta 标签
│ + sitemap.xml │
└─────────────────┘
│
▼
┌─────────────────┐
│ 4. 部署到 CDN │
└─────────────────┘
4.4 运行时数据流
用户请求页面
│
▼
┌─────────────────┐
│ CDN 返回预渲染 │──── 搜索引擎直接抓取完整 HTML
│ 的静态 HTML │
└─────────────────┘
│
▼
┌─────────────────┐
│ 浏览器加载 JS │──── 执行 Hydration
└─────────────────┘
│
▼
┌─────────────────┐
│ JS 接管为 SPA │──── 后续导航无刷新,客户端路由
│ 缓存层介入 │──── localStorage 缓存 API 响应
└─────────────────┘
五、缓存规范
5.1 策略
- 单层缓存:仅使用
localStorage,不保留内存缓存层
- 缓存键前缀:
ck_
- 默认 TTL:5 分钟
- 分类/标签缓存 TTL:30 分钟(变更频率低)
- 文章详情缓存 TTL:10 分钟
- 清理机制:过期自动清理;支持按模式批量清除
5.2 缓存范围
| 数据类型 |
是否缓存 |
TTL |
| 文章列表(分页) |
✅ |
5 分钟 |
| 单篇文章详情 |
✅ |
10 分钟 |
| 分类列表 |
✅ |
30 分钟 |
| 标签列表 |
✅ |
30 分钟 |
六、SEO 规范
6.1 预渲染要求
- 每篇文章、分类、标签页生成独立静态 HTML 文件
- 静态 HTML 包含完整正文内容(Markdown 已渲染为 HTML)
- 静态 HTML 包含完整导航结构(Header + Footer)
- 无需等待 JS 执行,搜索引擎即可抓取全部内容
6.2 Meta 标签要求(每页预注入)
| 标签 |
必填 |
说明 |
<title> |
✅ |
页面标题 | Chunking |
<meta name="description"> |
✅ |
文章摘要,160 字符以内 |
<meta property="og:title"> |
✅ |
页面标题 |
<meta property="og:description"> |
✅ |
文章摘要 |
<meta property="og:type"> |
✅ |
website 或 article |
<meta property="og:url"> |
✅ |
完整 URL |
<meta property="og:image"> |
❌ |
文章首图或默认图 |
<meta name="twitter:card"> |
✅ |
summary_large_image |
6.3 站点地图
- 构建时自动生成
sitemap.xml
- 包含所有页面 URL 及优先级
- 分类页、标签页、文章详情页全部纳入
七、Giscus 集成规范
| 属性 |
值 |
说明 |
data-mapping |
specific |
通过指定 Discussion number 绑定 |
data-term |
{post.number} |
博客文章 Discussion 的 number |
data-category |
Comments |
Giscus 专用评论分类 |
data-category-id |
环境变量 |
Giscus 分类 ID |
data-reactions-enabled |
1 |
启用表情反应 |
data-emit-metadata |
0 |
不发送元数据 |
data-input-position |
bottom |
评论框在底部 |
data-theme |
preferred_color_scheme |
跟随系统主题 |
data-lang |
zh-CN |
中文界面 |
关联规则:博客文章 Discussion 与 Giscus 评论 Discussion 为同一个 Discussion,通过 specific 映射模式绑定。
八、文件结构规范
chunking-blog/
├── package.json
├── package-lock.json
├── index.html
├── vite.config.js
├── build-ssg.js
├── .env
├── .gitignore
├── .github/
│ └── workflows/
│ └── deploy.yml
├── public/
│ └── robots.txt
├── src/
│ ├── main.js
│ ├── router.js
│ ├── api/
│ │ ├── github.js
│ │ └── cache.js
│ ├── components/
│ │ ├── Layout.js
│ │ ├── Header.js
│ │ ├── Footer.js
│ │ ├── PostCard.js
│ │ ├── Breadcrumb.js
│ │ ├── Pagination.js
│ │ └── Giscus.js
│ ├── pages/
│ │ ├── Home.js
│ │ ├── Categories.js
│ │ ├── CategoryDetail.js
│ │ ├── Tags.js
│ │ ├── TagDetail.js
│ │ ├── About.js
│ │ └── PostDetail.js
│ ├── utils/
│ │ ├── markdown.js
│ │ ├── seo.js
│ │ └── helpers.js
│ └── styles/
│ ├── variables.css
│ ├── base.css
│ ├── layout.css
│ ├── components.css
│ └── pages.css
└── dist/
├── index.html
├── categories.html
├── categories/
│ ├── astro.html
│ └── css.html
├── tags.html
├── tags/
│ ├── tailwind.html
│ └── vite.html
├── posts/
│ ├── 1.html
│ ├── 2.html
│ └── ...
├── about.html
└── sitemap.xml
九、开发约束清单
- 零前端框架:不使用 React/Vue/Angular/Svelte
- 原生 DOM 操作:
document.createElement、事件委托;innerHTML 仅用于 Markdown 渲染结果
- CSS 模块化:BEM 命名规范,不使用 CSS-in-JS
- 组件化:每个
.js 文件导出 render(props) 函数,返回 DOM 元素
- 路由守卫:页面切换滚动到顶部,更新
document.title
- 错误处理:API 失败展示友好错误页,提供重试按钮
- 加载状态:数据获取展示骨架屏或 loading spinner
- 响应式:支持移动端、平板、桌面三档断点
十、关键环境变量
| 变量名 |
必填 |
说明 |
示例 |
VITE_GITHUB_OWNER |
✅ |
GitHub 用户名/组织名 |
yourname |
VITE_GITHUB_REPO |
✅ |
存放 Discussions 的仓库名 |
blog |
VITE_GITHUB_TOKEN |
✅ |
GitHub Personal Access Token(构建时使用) |
ghp_xxxxxxxx |
VITE_GISCUS_REPO_ID |
✅ |
Giscus 仓库 ID |
从 giscus.app 获取 |
VITE_GISCUS_CATEGORY_ID |
✅ |
Giscus 分类 ID |
从 giscus.app 获取 |
VITE_BLOG_TITLE |
❌ |
博客标题 |
Chunking |
VITE_BLOG_DESCRIPTION |
❌ |
博客描述 |
A blog powered by GitHub Discussions |
十一、部署规范
| 项目 |
配置 |
| 平台 |
GitHub Pages(推荐,与内容仓库同源) |
| 触发方式 |
Push 到 main 分支 或 定时触发(每 6 小时) |
| 构建命令 |
npm run build |
| 输出目录 |
dist/ |
| 定时重建 |
通过 GitHub Actions schedule 事件,同步新发布的 Discussion |
十二、SEO 验收标准
| 检查项 |
要求 |
| Google 索引 |
所有页面可被正常抓取和索引 |
| 百度索引 |
所有页面可被正常抓取和索引 |
| 社交分享 |
Twitter/Facebook/微信 抓取显示正确标题、描述、图片 |
| 站点地图 |
sitemap.xml 包含全部 URL,可被搜索引擎读取 |
| 无 JS 依赖 |
禁用 JavaScript 后,页面内容完整可读 |
以上为修正后的完整 最新需求文档 v1.3。主要修正:
- ✅ 补充
package.json 到文件结构规范
- ✅ 补充
package-lock.json 到文件结构规范
- ✅ 补充
.gitignore 到文件结构规范
- ✅ 为每个文件增加详细注释说明其用途