最新需求文档 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"> websitearticle
<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              # 项目依赖配置(name, version, scripts, dependencies, devDependencies)
├── package-lock.json         # 依赖版本锁定文件
├── index.html                # SPA 入口 HTML 模板(运行时)
├── vite.config.js            # Vite 构建配置 + SSG 插件入口
├── build-ssg.js              # 构建时 SSG 脚本(构建时执行)
├── .env                      # 环境变量(不提交到版本控制)
├── .gitignore                # Git 忽略规则(node_modules, dist, .env 等)
├── .github/
│   └── workflows/
│       └── deploy.yml        # GitHub Actions CI 自动构建部署配置
├── public/
│   └── robots.txt            # 搜索引擎爬虫规则
├── src/
│   ├── main.js               # 应用入口:Hydration 初始化、路由注册
│   ├── router.js             # SPA Router 核心实现(History API、动态路由、404)
│   ├── api/
│   │   ├── github.js         # GitHub API 封装(Octokit + 缓存集成)
│   │   └── cache.js          # 精简单层 localStorage 缓存(~80 行)
│   ├── components/
│   │   ├── Layout.js         # 根布局组件(Header + Main + Footer)
│   │   ├── Header.js         # 导航栏组件(Logo + 导航链接)
│   │   ├── Footer.js         # 页脚组件
│   │   ├── PostCard.js       # 文章卡片组件
│   │   ├── Breadcrumb.js     # 面包屑导航组件
│   │   ├── Pagination.js     # 分页组件
│   │   └── Giscus.js         # Giscus 评论封装组件
│   ├── pages/
│   │   ├── Home.js           # 首页:文章列表 + 分页
│   │   ├── Categories.js     # 分类列表页:分类卡片网格
│   │   ├── CategoryDetail.js # 分类详情页:面包屑 + 统计 + 文章列表
│   │   ├── Tags.js           # 标签列表页:标签云
│   │   ├── TagDetail.js      # 标签详情页:面包屑 + 统计 + 文章列表
│   │   ├── About.js          # 关于页:博客简介
│   │   └── PostDetail.js     # 文章详情页:面包屑 + 内容 + Giscus 评论
│   ├── utils/
│   │   ├── markdown.js       # Marked.js + highlight.js 配置与渲染
│   │   ├── seo.js            # 运行时 meta 标签动态注入工具(备用)
│   │   └── helpers.js        # 通用工具函数(日期格式化、摘要提取、slugify 等)
│   └── styles/
│       ├── variables.css     # CSS 变量:颜色、间距、字体、断点
│       ├── base.css          # CSS 重置与基础样式
│       ├── layout.css        # 布局相关样式(Header、Footer、容器)
│       ├── components.css    # 组件样式(PostCard、Breadcrumb、Pagination 等)
│       └── pages.css         # 页面特定样式
└── dist/                     # 构建输出目录(由 Vite 生成,含 SSG 预渲染结果)
    ├── 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

九、开发约束清单

  1. 零前端框架:不使用 React/Vue/Angular/Svelte
  2. 原生 DOM 操作document.createElement、事件委托;innerHTML 仅用于 Markdown 渲染结果
  3. CSS 模块化:BEM 命名规范,不使用 CSS-in-JS
  4. 组件化:每个 .js 文件导出 render(props) 函数,返回 DOM 元素
  5. 路由守卫:页面切换滚动到顶部,更新 document.title
  6. 错误处理:API 失败展示友好错误页,提供重试按钮
  7. 加载状态:数据获取展示骨架屏或 loading spinner
  8. 响应式:支持移动端、平板、桌面三档断点

十、关键环境变量

变量名 必填 说明 示例
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。主要修正:

  1. ✅ 补充 package.json 到文件结构规范
  2. ✅ 补充 package-lock.json 到文件结构规范
  3. ✅ 补充 .gitignore 到文件结构规范
  4. ✅ 为每个文件增加详细注释说明其用途