487 lines
12 KiB
Markdown
487 lines
12 KiB
Markdown
# Frontend Public Docs Site Plan
|
||
|
||
## 目标
|
||
|
||
新增一个公开访问的 `/docs` 页面,作为 Planet 的开发设计文档与使用手册入口。
|
||
|
||
这个页面应类似常见开源软件文档站:
|
||
|
||
- 不需要登录即可访问
|
||
- 与 `/earth` 和 admin 后台平级,但视觉和信息架构独立
|
||
- 直接整理并展示仓库内 `docs/technical` 的 Markdown 文档
|
||
- 支持搜索、分类导航、文档目录和内部跳转
|
||
- 让 `docs/technical` 继续作为文档真源,避免页面内容和仓库文档漂移
|
||
|
||
## 非目标
|
||
|
||
本阶段不做:
|
||
|
||
- 后端全文搜索服务
|
||
- 数据库驱动的 CMS
|
||
- 独立文档构建系统,例如 Docusaurus / VitePress
|
||
- 每篇文档单独手写 React 页面
|
||
- 用户权限、编辑器、在线保存或评论功能
|
||
- 把 `docs/plans`、`docs/deprecated` 全量公开为正式手册
|
||
|
||
后续可以再决定是否把 plans / deprecated 做成独立的“路线图 / 历史归档”分区。
|
||
|
||
## 技术路线
|
||
|
||
### 推荐方案:Markdown 直接渲染
|
||
|
||
使用 Vite 在前端构建阶段直接加载 `docs/technical/**/*.md`:
|
||
|
||
```ts
|
||
const modules = import.meta.glob('../../../docs/technical/**/*.md', {
|
||
query: '?raw',
|
||
import: 'default',
|
||
})
|
||
```
|
||
|
||
这样每篇 Markdown 文件仍然留在仓库文档目录中,`/docs` 页面只是读取、索引和渲染这些文档。
|
||
|
||
当前项目已经满足主要前提:
|
||
|
||
- 前端使用 Vite + React
|
||
- `frontend/vite.config.ts` 已配置 `server.fs.allow: ['..']`
|
||
- 已有 `MarkdownRenderer` 可作为基础
|
||
- `docs/technical` 文档数量较少,前端本地搜索足够
|
||
|
||
### 不推荐方案:每篇文档单独写 React
|
||
|
||
不建议把每篇文档重写成 `.tsx` 页面,因为:
|
||
|
||
- 文档会出现两份真源
|
||
- 修改技术文档时还要同步 UI 页面
|
||
- 计划文档、技术上下文、变量表这类内容天然适合 Markdown
|
||
- 后续新增文档的成本会变高
|
||
|
||
只有当某篇文档需要强交互演示、实时图表或复杂 UI 时,才考虑给该文档补充一个 React 组件扩展。
|
||
|
||
## 信息架构
|
||
|
||
### 公开路由
|
||
|
||
新增:
|
||
|
||
- `/docs`
|
||
- `/docs/:slug`
|
||
|
||
路由行为:
|
||
|
||
- `/docs` 默认打开 `docs/technical/README.md`,或打开人工指定的首页文档
|
||
- `/docs/:slug` 打开对应技术文档
|
||
- 未找到文档时显示 docs 专属 404,而不是跳回 admin
|
||
- `/docs` 加入 `App.tsx` 的公开路由白名单
|
||
|
||
### 文档分类
|
||
|
||
将 `docs/technical` 中的现有文档整理进以下分组:
|
||
|
||
#### Overview
|
||
|
||
- `README.md`
|
||
|
||
#### Earth
|
||
|
||
- `earth-frontend-context.md`
|
||
- `earth-layer-style-reference.md`
|
||
- `earth-render-layer-order.md`
|
||
- `earth-satellite-footprint-policy.md`
|
||
- `earth-bgp-context.md`
|
||
- `earth-news-live-streams-collector-format.md`
|
||
|
||
#### Frontend
|
||
|
||
- `frontend-admin-frontend-context.md`
|
||
- `frontend-layout-guidelines.md`
|
||
|
||
#### Backend
|
||
|
||
- `backend-collectors.md`
|
||
- `backend-system-service-control.md`
|
||
|
||
#### Agents
|
||
|
||
- `agents-aiprovider.md`
|
||
|
||
#### Ops
|
||
|
||
- `ops-docker-compose-buildx-upgrade.md`
|
||
|
||
### 页面布局
|
||
|
||
桌面端:
|
||
|
||
- 顶部:产品名、搜索框、当前文档标题
|
||
- 左侧:文档分组导航
|
||
- 中间:Markdown 正文
|
||
- 右侧:当前文档目录,也就是 h2 / h3 anchors
|
||
|
||
移动端:
|
||
|
||
- 顶部固定搜索入口
|
||
- 导航折叠为抽屉或下拉
|
||
- 正文单列显示
|
||
- 当前文档目录折叠为“本文目录”
|
||
|
||
视觉风格:
|
||
|
||
- 像开源软件 docs 页面,清晰、安静、可长时间阅读
|
||
- 不复用 admin 后台的重操作感布局
|
||
- 不做 Earth 的沉浸式深色 HUD 风格
|
||
- 优先阅读性、扫描效率和代码/表格可读性
|
||
|
||
## 前端实现设计
|
||
|
||
### 文件结构
|
||
|
||
建议新增:
|
||
|
||
```text
|
||
frontend/src/pages/Docs/
|
||
Docs.tsx
|
||
docs-content.ts
|
||
docs-search.ts
|
||
docs-slugs.ts
|
||
Docs.css
|
||
```
|
||
|
||
可选拆分:
|
||
|
||
```text
|
||
frontend/src/pages/Docs/components/
|
||
DocsSidebar.tsx
|
||
DocsSearch.tsx
|
||
DocsToc.tsx
|
||
DocsMarkdown.tsx
|
||
```
|
||
|
||
如果初版代码量不大,可以先保持在 `Docs.tsx` + 少量 helper 文件中,避免过度拆分。
|
||
|
||
### 文档注册表
|
||
|
||
创建一个 registry,负责将 Markdown 文件路径映射为文档元信息:
|
||
|
||
```ts
|
||
interface DocsEntry {
|
||
slug: string
|
||
path: string
|
||
title: string
|
||
group: string
|
||
order: number
|
||
loader: () => Promise<string>
|
||
}
|
||
```
|
||
|
||
slug 规则:
|
||
|
||
- `docs/technical/README.md` -> `overview`
|
||
- `docs/technical/earth-layer-style-reference.md` -> `earth-layer-style-reference`
|
||
- 只暴露稳定 slug,不暴露本机绝对路径
|
||
|
||
标题规则:
|
||
|
||
- 优先读取 Markdown 第一个 `# heading`
|
||
- 没有 h1 时用人工 registry title
|
||
- 再 fallback 到文件名转换标题
|
||
|
||
### Markdown 渲染
|
||
|
||
初版可以复用现有:
|
||
|
||
- [frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx](/home/ray/dev/linkong/planet/frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx)
|
||
|
||
但建议增强或包装为 docs 专用渲染:
|
||
|
||
- heading 生成稳定 `id`
|
||
- 右侧 TOC 使用同一套 heading 解析结果
|
||
- 内部 Markdown 链接转换为 `/docs/:slug`
|
||
- 外部链接保留 `target="_blank" rel="noreferrer"`
|
||
- 表格横向滚动
|
||
- 代码块保留等宽字体和语言标记
|
||
- 支持 GitHub 风格的相对文档链接
|
||
|
||
内部链接转换示例:
|
||
|
||
- `earth-render-layer-order.md` -> `/docs/earth-render-layer-order`
|
||
- `./earth-layer-style-reference.md` -> `/docs/earth-layer-style-reference`
|
||
- `/home/ray/dev/linkong/planet/docs/technical/foo.md` -> `/docs/foo`
|
||
|
||
对非 `docs/technical` 的链接:
|
||
|
||
- 初版可保留原始链接文本
|
||
- 或显示为不可跳转的 repo path
|
||
- 后续再扩展为跨文档区导航
|
||
|
||
### 搜索
|
||
|
||
初版使用纯前端本地搜索。
|
||
|
||
索引字段:
|
||
|
||
- title
|
||
- slug
|
||
- group
|
||
- headings
|
||
- markdown 正文纯文本
|
||
|
||
搜索策略:
|
||
|
||
- 页面首次加载后异步加载所有 `docs/technical` Markdown
|
||
- 生成内存索引
|
||
- 用户输入时本地过滤
|
||
- 简单打分即可:
|
||
- 标题命中权重最高
|
||
- heading 命中其次
|
||
- 文件名 / slug 命中其次
|
||
- 正文命中最低
|
||
|
||
搜索结果展示:
|
||
|
||
- 文档标题
|
||
- 分组
|
||
- 命中的 heading 或正文摘要
|
||
- 点击跳转到文档
|
||
|
||
当前只有 13 篇文档,不需要 Lunr、Fuse 或后端搜索。后续文档数量显著增长时,再考虑引入轻量搜索库。
|
||
|
||
### 路由接入
|
||
|
||
修改:
|
||
|
||
- [frontend/src/App.tsx](/home/ray/dev/linkong/planet/frontend/src/App.tsx)
|
||
|
||
新增 lazy import:
|
||
|
||
```ts
|
||
const Docs = lazy(() => import('./pages/Docs/Docs'))
|
||
```
|
||
|
||
公开路由:
|
||
|
||
```ts
|
||
const publicPaths = new Set(['/', '/earth', '/docs'])
|
||
```
|
||
|
||
注意:`/docs/:slug` 不能只用精确匹配 `Set`。
|
||
|
||
建议改为:
|
||
|
||
```ts
|
||
const isPublicRoute =
|
||
window.location.pathname === '/' ||
|
||
window.location.pathname === '/earth' ||
|
||
window.location.pathname === '/docs' ||
|
||
window.location.pathname.startsWith('/docs/')
|
||
```
|
||
|
||
新增 routes:
|
||
|
||
```tsx
|
||
<Route path="/docs" element={<Docs />} />
|
||
<Route path="/docs/:slug" element={<Docs />} />
|
||
```
|
||
|
||
### 样式
|
||
|
||
建议独立 `Docs.css`,不依赖 admin 页面布局。
|
||
|
||
核心样式要求:
|
||
|
||
- 文档正文最大宽度控制在适合阅读的范围
|
||
- 表格横向滚动,不撑破布局
|
||
- 代码块横向滚动
|
||
- 左侧导航固定或 sticky
|
||
- 右侧 TOC sticky
|
||
- 移动端隐藏右侧 TOC,导航折叠
|
||
- 搜索结果浮层或独立面板不遮挡正文阅读
|
||
|
||
注意:
|
||
|
||
- 不做营销 hero
|
||
- 不做卡片堆叠式首页
|
||
- 首页第一屏应直接是文档入口和内容,而不是宣传页
|
||
|
||
## 实施阶段
|
||
|
||
### Phase 1:基础文档站
|
||
|
||
目标:
|
||
|
||
- `/docs` 可公开访问
|
||
- 能看到 `docs/technical` 文档列表
|
||
- 能打开每篇 Markdown
|
||
- 能基本渲染标题、段落、列表、代码块、表格
|
||
|
||
任务:
|
||
|
||
- 新增 `Docs` 页面
|
||
- 新增 docs registry
|
||
- 接入 Vite raw Markdown loading
|
||
- 接入 `/docs` 和 `/docs/:slug`
|
||
- 加入公开路由白名单
|
||
- 初版 CSS 布局
|
||
|
||
验收:
|
||
|
||
- 未登录访问 `/docs` 不跳转登录
|
||
- `/docs/earth-layer-style-reference` 可打开样式参考文档
|
||
- `/docs/backend-collectors` 可打开后端采集器文档
|
||
- 构建通过:`source ~/.zshrc && bun run build`
|
||
|
||
### Phase 2:搜索与 TOC
|
||
|
||
目标:
|
||
|
||
- 支持本地搜索所有 technical 文档
|
||
- 当前文档右侧显示目录
|
||
- 搜索结果可跳转
|
||
|
||
任务:
|
||
|
||
- 实现 heading parser
|
||
- 实现 TOC 组件
|
||
- 实现 search index
|
||
- 搜索结果显示文档标题、分组和摘要
|
||
- 当前文档标题与 active nav 高亮
|
||
|
||
验收:
|
||
|
||
- 搜索 `Fresnel` 能找到 Earth 图层样式文档
|
||
- 搜索 `collector` 能找到 backend collectors
|
||
- 点击搜索结果进入对应文档
|
||
- 右侧 TOC 点击后滚动到对应 heading
|
||
|
||
### Phase 3:链接清理与文档体验
|
||
|
||
目标:
|
||
|
||
- Markdown 内部链接在 docs 站内自然跳转
|
||
- 长表格、代码块、绝对路径链接的显示更友好
|
||
|
||
任务:
|
||
|
||
- 转换 `docs/technical/*.md` 相对链接
|
||
- 转换 repo 内 technical 文档绝对路径
|
||
- 外链新窗口打开
|
||
- 文件路径链接以代码样式显示
|
||
- 增强空状态和 404
|
||
|
||
验收:
|
||
|
||
- 从 `docs/technical/README.md` 点击 technical 文档链接进入 `/docs/:slug`
|
||
- 不支持的 repo 内路径不会导致前端崩溃
|
||
- 外部链接行为正常
|
||
|
||
### Phase 4:文档内容整理
|
||
|
||
目标:
|
||
|
||
- `docs/technical` 的首页适合作为公开手册入口
|
||
- 每篇文档标题、摘要和分类清晰
|
||
|
||
任务:
|
||
|
||
- 检查每篇文档是否有唯一 h1
|
||
- 给 README 补公开手册导览
|
||
- 必要时补文档摘要
|
||
- 保持文档内容仍然服务开发维护,不改成营销语气
|
||
|
||
验收:
|
||
|
||
- `/docs` 首页能说明各技术文档用途
|
||
- 左侧分类和 README 内容一致
|
||
- 没有明显重复、过期或找不到的主入口
|
||
|
||
## 需要改动的文件
|
||
|
||
预计新增:
|
||
|
||
- `frontend/src/pages/Docs/Docs.tsx`
|
||
- `frontend/src/pages/Docs/Docs.css`
|
||
- `frontend/src/pages/Docs/docs-content.ts`
|
||
- `frontend/src/pages/Docs/docs-search.ts`
|
||
|
||
预计修改:
|
||
|
||
- `frontend/src/App.tsx`
|
||
- `frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx` 或新增 docs 专用 wrapper
|
||
- `docs/technical/README.md`
|
||
|
||
可选修改:
|
||
|
||
- `frontend/src/index.css`,只放全局极少量 docs shell reset 时才需要
|
||
- `docs/CHANGELOG.md`,实施完成后记录
|
||
- `docs/version-history.md`,若进入版本发布流程再更新
|
||
|
||
## 风险与注意事项
|
||
|
||
### 构建路径风险
|
||
|
||
Vite 从 `frontend/src` 读取 `../../../docs/technical/**/*.md` 时,需要确认开发和生产构建都可解析。
|
||
|
||
缓解:
|
||
|
||
- 使用相对路径 glob
|
||
- 构建验证必须跑 `source ~/.zshrc && bun run build`
|
||
- 不使用运行时 `fetch('/docs/...')` 读取仓库文件,避免生产环境缺文件
|
||
|
||
### Markdown 能力不足
|
||
|
||
现有 `MarkdownRenderer` 是轻量实现,可能不完整支持所有 GitHub Markdown。
|
||
|
||
缓解:
|
||
|
||
- 初版优先覆盖当前 `docs/technical` 实际用到的语法
|
||
- 若后续需要脚注、嵌套列表、复杂代码高亮,再考虑引入 `react-markdown` 等依赖
|
||
|
||
### Bundle 体积
|
||
|
||
把所有 Markdown 打进前端 bundle 会增加体积。
|
||
|
||
当前文档数量少,风险可接受。
|
||
|
||
缓解:
|
||
|
||
- 使用 lazy page chunk
|
||
- Markdown loader 保持异步
|
||
- 搜索索引在 `/docs` 页面内初始化,不影响 `/earth` 和 admin 首屏
|
||
|
||
### 公开内容边界
|
||
|
||
`docs/technical` 会被公开展示,需要避免包含密钥、内部机器地址、临时方案或不应公开的操作细节。
|
||
|
||
缓解:
|
||
|
||
- 实施前快速审阅 `docs/technical`
|
||
- 暂不公开 `docs/plans` 和 `docs/deprecated`
|
||
- 以后如需公开更多文档,先建立 allowlist
|
||
|
||
## 验收清单
|
||
|
||
- `/docs` 未登录可访问
|
||
- `/docs/:slug` 未登录可访问
|
||
- `/docs` 不影响 `/earth`
|
||
- 未登录访问 admin 仍然跳登录
|
||
- 左侧导航包含所有 `docs/technical` 文档
|
||
- 文档按 Overview / Earth / Frontend / Backend / Agents / Ops 分类
|
||
- Markdown 表格正常显示并可横向滚动
|
||
- 代码块正常显示并可横向滚动
|
||
- 搜索可搜索标题、heading 和正文
|
||
- 搜索结果点击可跳转
|
||
- 当前文档 TOC 可跳转
|
||
- 不存在的 slug 显示 docs 404
|
||
- `source ~/.zshrc && bun run build` 通过
|
||
|
||
## 后续增强
|
||
|
||
- 给文档页面增加复制 heading 链接按钮
|
||
- 给代码块增加复制按钮
|
||
- 增加“上一页 / 下一页”导航
|
||
- 增加最近更新信息
|
||
- 从 git metadata 读取文档更新时间
|
||
- 引入轻量全文搜索库
|
||
- 支持 plans / deprecated 独立分区
|
||
- 增加页面内反馈入口
|