|
| 1 | +--- |
| 2 | +title: 系统设计 |
| 3 | +description: ObjectDocs 完整系统设计文档 — 架构、技术决策和组件概览。 |
| 4 | +--- |
| 5 | + |
| 6 | +import { FileJson, Layers, Cpu, Zap, GitBranch, Package, Globe, Code } from 'lucide-react'; |
| 7 | + |
| 8 | +# 系统设计文档 |
| 9 | + |
| 10 | +本文档提供 ObjectDocs 的完整技术设计概览,涵盖系统架构、包结构、数据流和关键设计决策。 |
| 11 | + |
| 12 | +**版本**: v0.2.12 | **最后更新**: 2026-02-08 |
| 13 | + |
| 14 | +## 1. 系统概述 |
| 15 | + |
| 16 | +ObjectDocs 是一个基于 Next.js 和 Fumadocs 构建的**元数据驱动文档引擎**,专为 ObjectStack 低代码生态系统设计。它遵循严格的**配置即代码**理念,文档结构由数据(JSON)定义,而非代码(React)。 |
| 17 | + |
| 18 | +### 设计目标 |
| 19 | + |
| 20 | +<Cards> |
| 21 | +<Card icon={<FileJson />} title="元数据驱动"> |
| 22 | +导航、侧边栏和页面排序完全通过 `meta.json` 文件和 `docs.site.json` 配置定义。内容创作者无需接触 React 代码。 |
| 23 | +</Card> |
| 24 | +<Card icon={<Layers />} title="关注点分离"> |
| 25 | +系统严格分离三个层次:**展示层**(React/Next.js 站点引擎)、**配置层**(JSON 文件)和**内容层**(MDX 文档)。 |
| 26 | +</Card> |
| 27 | +<Card icon={<Package />} title="Monorepo 架构"> |
| 28 | +项目组织为 pnpm 工作区 monorepo,包含两个核心包(`@objectdocs/cli` 和 `@objectdocs/site`)以及共享的内容层。 |
| 29 | +</Card> |
| 30 | +<Card icon={<Globe />} title="国际化优先"> |
| 31 | +多语言支持内置于核心架构中,支持语言特定的 MDX 文件和 6 种语言的预置 UI 翻译。 |
| 32 | +</Card> |
| 33 | +</Cards> |
| 34 | + |
| 35 | +## 2. 架构概览 |
| 36 | + |
| 37 | +### 2.1 高层架构 |
| 38 | + |
| 39 | +```text |
| 40 | +┌─────────────────────────────────────────────────────────┐ |
| 41 | +│ ObjectDocs 系统 │ |
| 42 | +├──────────────┬──────────────────┬───────────────────────┤ |
| 43 | +│ @objectdocs │ @objectdocs │ 内容层 │ |
| 44 | +│ /cli │ /site │ │ |
| 45 | +│ │ │ │ |
| 46 | +│ 命令: │ Next.js 16 + │ content/ │ |
| 47 | +│ • init │ Fumadocs 16 │ ├── docs.site.json │ |
| 48 | +│ • dev │ │ ├── docs/ │ |
| 49 | +│ • build │ App Router │ │ ├── meta.json │ |
| 50 | +│ • start │ React Server │ │ ├── index.mdx │ |
| 51 | +│ • translate │ Components │ │ └── ... │ |
| 52 | +│ │ │ └── public/ │ |
| 53 | +├──────────────┼──────────────────┼───────────────────────┤ |
| 54 | +│ CLI 层 │ 展示层 │ 数据层 │ |
| 55 | +│ (工具链) │ (渲染) │ (配置 + 内容) │ |
| 56 | +└──────────────┴──────────────────┴───────────────────────┘ |
| 57 | +``` |
| 58 | + |
| 59 | +### 2.2 包依赖关系图 |
| 60 | + |
| 61 | +```text |
| 62 | +根工作区 (objectdocs v1.0.0) |
| 63 | +├── @objectdocs/cli (v0.2.12) |
| 64 | +│ ├── 依赖: @objectdocs/site (workspace:*) |
| 65 | +│ ├── cac (CLI 框架) |
| 66 | +│ ├── openai (AI 翻译) |
| 67 | +│ └── dotenv (环境配置) |
| 68 | +└── @objectdocs/site (v0.2.12) |
| 69 | + ├── next (^16.1.2) |
| 70 | + ├── fumadocs-core (^16.4.7) |
| 71 | + ├── fumadocs-ui (^16.4.7) |
| 72 | + ├── fumadocs-mdx (^14.2.5) |
| 73 | + ├── react (^19.2.3) |
| 74 | + ├── tailwindcss (^4.1.18) |
| 75 | + └── typescript (^5.9.3) |
| 76 | +``` |
| 77 | + |
| 78 | +## 3. 核心组件 |
| 79 | + |
| 80 | +### 3.1 CLI 包 (`@objectdocs/cli`) |
| 81 | + |
| 82 | +CLI 是 ObjectDocs 的主要开发者接口。基于 [CAC](https://github.com/cacjs/cac) 框架构建,提供 5 个命令: |
| 83 | + |
| 84 | +| 命令 | 用途 | 关键行为 | |
| 85 | +|------|------|---------| |
| 86 | +| `init` | 初始化新文档项目 | 将 `@objectdocs/site` 复制到 `content/.fumadocs`,安装依赖,更新 `.gitignore` | |
| 87 | +| `dev` | 启动开发服务器 | 运行在端口 7777,监听 `docs.site.json` 变更,同步公共资源 | |
| 88 | +| `build` | 生产环境构建 | 支持静态导出(`out/`)和动态独立(`.next/`)两种模式 | |
| 89 | +| `start` | 启动生产服务器 | 静态模式使用 `serve`,动态模式使用 Next.js 服务器 | |
| 90 | +| `translate` | AI 驱动的翻译 | 使用 OpenAI API,支持 `--all` 参数,生成语言特定的 `.mdx` 文件 | |
| 91 | + |
| 92 | +**设计决策**:CLI 在初始化时将整个 `@objectdocs/site` 包复制到 `content/.fumadocs`,而不是作为运行时依赖使用。这确保了文档引擎和用户内容之间的完全隔离,允许自定义站点而不影响包本身。 |
| 93 | + |
| 94 | +### 3.2 站点包 (`@objectdocs/site`) |
| 95 | + |
| 96 | +站点包是一个完整的 Next.js 应用模板,作为文档渲染引擎。 |
| 97 | + |
| 98 | +**核心组件**: |
| 99 | + |
| 100 | +| 组件 | 文件 | 职责 | |
| 101 | +|------|------|------| |
| 102 | +| 根布局 | `app/layout.tsx` | HTML 外壳、Provider、全局样式 | |
| 103 | +| 语言路由 | `app/[lang]/layout.tsx` | i18n 布局与 Fumadocs Provider | |
| 104 | +| 文档页面 | `app/[lang]/docs/[[...slug]]/page.tsx` | MDX 渲染、TOC、导航 | |
| 105 | +| 搜索 API | `app/api/search/route.ts` | 全文搜索端点 | |
| 106 | +| i18n 配置 | `lib/i18n.ts` | 语言定义和 UI 翻译 | |
| 107 | +| 站点配置 | `lib/config.ts` | 加载并合并 `docs.site.json` | |
| 108 | +| 内容加载器 | `lib/source.ts` | 带 i18n 的 Fumadocs 内容源 | |
| 109 | + |
| 110 | +### 3.3 内容层 |
| 111 | + |
| 112 | +内容层是定义文档站点的用户数据: |
| 113 | + |
| 114 | +```text |
| 115 | +content/ |
| 116 | +├── docs.site.json # 全局站点配置 |
| 117 | +│ ├── branding # Logo、名称、主题颜色 |
| 118 | +│ ├── links # 导航栏链接 |
| 119 | +│ ├── sidebar # 侧边栏行为配置 |
| 120 | +│ ├── toc # 目录设置 |
| 121 | +│ ├── footer # 页脚版权文本 |
| 122 | +│ ├── page # 页面功能(编辑链接、最后更新) |
| 123 | +│ ├── content # 内容功能(数学公式、代码主题) |
| 124 | +│ ├── i18n # 语言配置 |
| 125 | +│ └── build # 构建模式(export/standalone) |
| 126 | +├── public/ # 静态资源(图片、字体) |
| 127 | +└── docs/ |
| 128 | + ├── meta.json # 根导航结构 |
| 129 | + ├── index.mdx # 首页(英文) |
| 130 | + ├── index.cn.mdx # 首页(中文) |
| 131 | + └── getting-started/ |
| 132 | + ├── meta.json # 章节页面排序 |
| 133 | + ├── index.mdx # 章节首页 |
| 134 | + └── ... |
| 135 | +``` |
| 136 | + |
| 137 | +## 4. 数据流 |
| 138 | + |
| 139 | +### 4.1 构建时数据流 |
| 140 | + |
| 141 | +<Steps> |
| 142 | + |
| 143 | +### 内容发现 |
| 144 | +Fumadocs MDX 源加载器扫描 `DOCS_DIR` 目录中的所有 `.mdx` 文件和 `meta.json` 文件。文件按语言后缀组织(如 `.cn.mdx` 为中文)。 |
| 145 | + |
| 146 | +### 配置合并 |
| 147 | +站点从内容目录读取 `docs.site.json` 并与 `lib/config.ts` 中的默认配置值合并,生成完整的站点配置。 |
| 148 | + |
| 149 | +### 导航树构建 |
| 150 | +每个目录中的 `meta.json` 文件定义页面排序和章节标题。Fumadocs 从这些文件构建层次化的导航树。 |
| 151 | + |
| 152 | +### MDX 编译 |
| 153 | +每个 `.mdx` 文件通过 Fumadocs MDX 管道(含 remark/rehype 插件)编译,生成 React Server Components。 |
| 154 | + |
| 155 | +### 静态生成 |
| 156 | +Next.js App Router 为每个路由生成静态页面。在独立模式下,页面可以通过 ISR 进行服务端渲染。 |
| 157 | + |
| 158 | +</Steps> |
| 159 | + |
| 160 | +### 4.2 运行时数据流 |
| 161 | + |
| 162 | +```text |
| 163 | +用户请求 → Next.js 路由 → 语言检测 → 页面解析 |
| 164 | + → MDX 内容渲染 (RSC) → Fumadocs UI 布局 → HTML 响应 |
| 165 | +``` |
| 166 | + |
| 167 | +### 4.3 翻译数据流 |
| 168 | + |
| 169 | +```text |
| 170 | +源 MDX → CLI translate 命令 → OpenAI API → 翻译后的 MDX |
| 171 | + → 语言特定文件 (如 .cn.mdx) → 内容发现 |
| 172 | +``` |
| 173 | + |
| 174 | +## 5. 配置系统设计 |
| 175 | + |
| 176 | +### 5.1 `docs.site.json` 模式 |
| 177 | + |
| 178 | +站点配置文件支持以下部分: |
| 179 | + |
| 180 | +```json |
| 181 | +{ |
| 182 | + "site": { |
| 183 | + "title": "站点标题", |
| 184 | + "description": "站点描述", |
| 185 | + "url": "https://example.com", |
| 186 | + "favicon": "/favicon.ico" |
| 187 | + }, |
| 188 | + "branding": { |
| 189 | + "name": "品牌名称", |
| 190 | + "logo": { "light": "/logo-light.svg", "dark": "/logo-dark.svg" }, |
| 191 | + "themeColor": "#7c3aed", |
| 192 | + "borderRadius": "0.5rem" |
| 193 | + }, |
| 194 | + "links": [{ "text": "首页", "url": "/" }], |
| 195 | + "sidebar": { "collapsible": true, "defaultOpenLevel": 1 }, |
| 196 | + "toc": { "enabled": true, "depth": 3 }, |
| 197 | + "footer": { "copyright": "© 2026" }, |
| 198 | + "page": { |
| 199 | + "lastUpdate": true, |
| 200 | + "editOnGithub": { "owner": "org", "repo": "repo" } |
| 201 | + }, |
| 202 | + "content": { "codeTheme": "vesper", "imageZoom": true }, |
| 203 | + "i18n": { |
| 204 | + "defaultLanguage": "en", |
| 205 | + "languages": ["en", "cn"] |
| 206 | + }, |
| 207 | + "build": { "mode": "export" } |
| 208 | +} |
| 209 | +``` |
| 210 | + |
| 211 | +### 5.2 `meta.json` 模式 |
| 212 | + |
| 213 | +每个目录可以包含 `meta.json` 来控制导航: |
| 214 | + |
| 215 | +```json |
| 216 | +{ |
| 217 | + "title": "章节标题", |
| 218 | + "pages": ["page-a", "page-b", "sub-directory"] |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +**关键规则**:侧边栏导航**永远不**在 React 组件中定义。所有导航结构变更通过 `meta.json` 文件进行。 |
| 223 | + |
| 224 | +## 6. 国际化架构 |
| 225 | + |
| 226 | +### 6.1 支持的语言 |
| 227 | + |
| 228 | +| 代码 | 语言 | UI 翻译 | |
| 229 | +|------|------|---------| |
| 230 | +| `en` | English | ✅ 完整 | |
| 231 | +| `cn` | 中文 | ✅ 完整 | |
| 232 | +| `ja` | 日本語 | ✅ 完整 | |
| 233 | +| `fr` | Français | ✅ 完整 | |
| 234 | +| `de` | Deutsch | ✅ 完整 | |
| 235 | +| `es` | Español | ✅ 完整 | |
| 236 | + |
| 237 | +### 6.2 内容翻译策略 |
| 238 | + |
| 239 | +- **基于文件**:每种语言有独立的 MDX 文件(如英文 `index.mdx`,中文 `index.cn.mdx`) |
| 240 | +- **回退机制**:如果翻译文件不存在,使用默认语言版本 |
| 241 | +- **AI 翻译**:`translate` CLI 命令使用 OpenAI 自动生成翻译 |
| 242 | +- **URL 路由**:URL 路径中的语言前缀(`/en/docs/...`、`/cn/docs/...`) |
| 243 | + |
| 244 | +## 7. 部署设计 |
| 245 | + |
| 246 | +### 7.1 构建模式 |
| 247 | + |
| 248 | +| 模式 | 输出 | 使用场景 | |
| 249 | +|------|------|---------| |
| 250 | +| `export`(静态) | `out/` 目录(HTML/CSS/JS) | CDN 托管、GitHub Pages、Vercel 静态 | |
| 251 | +| `standalone`(动态) | `.next/`(Node.js 服务器) | ISR、SSR、API 路由、Vercel Serverless | |
| 252 | + |
| 253 | +### 7.2 Vercel 部署 |
| 254 | + |
| 255 | +```text |
| 256 | +GitHub 推送 → Vercel 构建钩子 → pnpm build → Next.js 构建 |
| 257 | + → 静态资源 + Serverless 函数 → 边缘 CDN 分发 |
| 258 | +``` |
| 259 | + |
| 260 | +**关键设计决策**: |
| 261 | +- 独立输出模式,优化 Vercel serverless 支持 |
| 262 | +- 符号链接感知的构件复制,处理 monorepo 结构 |
| 263 | +- `vercel.json` 路由配置,支持简洁 URL |
| 264 | +- 通过 GitHub Actions 工作流实现预览部署 |
| 265 | + |
| 266 | +### 7.3 CI/CD 流水线 |
| 267 | + |
| 268 | +| 工作流 | 触发器 | 用途 | |
| 269 | +|--------|--------|------| |
| 270 | +| `ci.yml` | Push/PR | 构建验证 | |
| 271 | +| `release.yml` | Push to main | Changesets NPM 发布 | |
| 272 | +| `preview.yml` | PR | Vercel 预览部署 | |
| 273 | +| `test-lifecycle.yml` | Push/PR | 全面生命周期测试 | |
| 274 | +| `link-check.yml` | PR | 内容链接验证 | |
| 275 | + |
| 276 | +## 8. 技术栈 |
| 277 | + |
| 278 | +| 层级 | 技术 | 版本 | |
| 279 | +|------|------|------| |
| 280 | +| 运行时 | Next.js (App Router) | ^16.1.2 | |
| 281 | +| UI 框架 | React (Server Components) | ^19.2.3 | |
| 282 | +| 文档引擎 | Fumadocs | ^16.4.7 | |
| 283 | +| 样式 | Tailwind CSS | ^4.1.18 | |
| 284 | +| 语言 | TypeScript | ^5.9.3 | |
| 285 | +| 包管理器 | pnpm | 工作区 monorepo | |
| 286 | +| AI 集成 | OpenAI API | ^4.0.0 | |
| 287 | +| CLI 框架 | CAC | ^6.7.14 | |
| 288 | +| 内容格式 | MDX | 通过 fumadocs-mdx | |
| 289 | +| 部署 | Vercel | Serverless/Edge | |
| 290 | + |
| 291 | +## 9. 安全考虑 |
| 292 | + |
| 293 | +- **无硬编码密钥**:所有 API 密钥(如 OpenAI)通过环境变量加载 |
| 294 | +- **默认 Server Components**:最小化客户端 JavaScript 暴露 |
| 295 | +- **内容隔离**:文档内容与渲染引擎分离 |
| 296 | +- **依赖管理**:通过 Changesets 自动化管理,锁定版本 |
| 297 | + |
| 298 | +<Callout type="info"> |
| 299 | +本设计文档反映了 ObjectDocs v0.2.12 的当前状态。随着系统演进将持续更新。功能路线图请参阅[开发路线图](/docs/development-plan)。 |
| 300 | +</Callout> |
0 commit comments