> For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt.

# 工作原理

库把渲染拆成可以分别部署的阶段。理解这条管线和两种快照，就能判断什么时候该用根入口，什么时候该把解析放到服务端。

## 处理管线

```text
source
  │
  ├─（可选）/expand ─▶ 展开后的 source
  │
  ▼
/parse ─▶ WikitextDocument（解析快照）
  │
  ▼
/hast prepare ─▶ WikitextRenderDocument（渲染快照）
  │
  ▼
/view ─▶ React
```

| 阶段 | 入口              | 输入        | 输出                       | 是否必需  |
| -- | --------------- | --------- | ------------------------ | ----- |
| 展开 | `/expand`       | 源码与模板解析函数 | 展开后的解析文档                 | 可选    |
| 解析 | `/parse`、`/ast` | 源码        | `WikitextDocument`       | 必需    |
| 准备 | `/hast`         | 解析快照      | `WikitextRenderDocument` | 渲染前必需 |
| 渲染 | `/view`、根入口     | 渲染快照      | React 元素                 | 渲染时必需 |

`/expand` 的结果已经是解析文档，不需要再手动解析一次；直接交给 `prepareWikitext`。

## 两种快照

### 解析快照 `WikitextDocument`

```ts
interface WikitextDocument {
  readonly source: string;
  readonly ast: WikitextRoot;
  readonly syntax?: WikitextSyntaxRoot;
  readonly meta: WikitextDocumentMeta;
  readonly diagnostics: readonly WikitextDiagnostic[];
}
```

- `ast` 是归一化后的语义树，准备阶段不会修改它。
- `syntax` 只在 `retainSyntax: true` 时存在，用于源码坐标与 playground。
- 同一份源码配合不同的站点配置或 `pageName`，可能得到不同的 AST。

### 渲染快照 `WikitextRenderDocument`

```ts
interface WikitextRenderDocument {
  readonly source: string;
  readonly ast: WikitextRoot; // 插件处理后的工作树
  readonly hast: import("hast").Root; // 已清洗的最终 HAST
  readonly headings: readonly WikitextHeadingInfo[];
  readonly meta: WikitextRenderMeta;
  readonly diagnostics: readonly WikitextDiagnostic[];
}
```

- `hast` 已经包含目录、引用区与分类底栏，不需要在视图层再拼装。
- `ast` 是本次工作树的结果，节点 id 已经重新分配。
- `meta` 记录实际生效的策略、文案、标题策略与授权图片。
- `WikitextView` 只接受渲染快照，不接收源码。

查询节点时必须区分两份快照：不要用渲染快照里的 id 查原始解析快照。

## 为什么要拆成两段

解析成本高，而准备选项经常变化。缓存解析快照，就可以用不同的链接、图片、文案或插件重复准备，而不必重新解析。服务端准备、客户端渲染也是同一套快照：客户端不加载解析器，也不重跑插件。

准备阶段在克隆的工作树上执行，原始快照保持只读。快照是普通数据，可以放进缓存、跨 Worker 传递或经网络传输；恢复函数会重新校验结构与预算。

:::note
准备阶段并不只是渲染前的小调整。它决定 HAST 的最终内容与安全边界；跳过准备、直接把 HAST 交给视图不在支持范围内。
:::

## 语义归一化

上游解析器给出的是源码语法树。库在语义阶段完成结构归一化，React 层不再扫描源码。

无法安全或正确表达的结构会降级为源码卡片并写入诊断，不推断外观。模板、解析器函数、参数与文件默认输出占位，避免把“未求值”误当成“已求值”。

源码 HTML 按类别处理：允许的标签按白名单输出，禁止的标签整对丢弃并提示，未知标签降级。链接与图片在最终整理阶段再次校验协议、`target`、`rel` 与图片授权。

这套策略优先保证每一段输出都能解释、能审计，不追求最大化还原 Wikipedia。

## 入口与加载边界

| 入口         | 加载解析器 | 加载 React | 典型用途            |
| ---------- | ----- | -------- | --------------- |
| 根入口        | 是     | 是        | 客户端直接渲染源码       |
| `/view`    | 否     | 是        | 客户端只渲染准备好的快照    |
| `/parse`   | 是     | 否        | 服务端、Worker、缓存   |
| `/expand`  | 是     | 否        | 解析前展开模板         |
| `/hast`    | 否     | 否        | 准备、序列化、恢复       |
| `/ast`     | 否     | 否        | 纯数据处理与 AST 查询   |
| `/unified` | 否     | 否        | 显式注入解析器的 raw 模式 |
| `/configs` | 否     | 否        | 站点配置常量          |

完整导出清单见[入口总览](/zh/api/index.md)。

:::warning
React 入口在模块加载时创建 Context，并使用 `useId` / `useMemo`，因此只能在客户端组件中运行。根入口与 `/view` 的产物顶部带有 `"use client"` 指令，在 Next.js App Router 等环境中可以直接使用。服务端只应调用 `/parse`、`/hast` 等无 React 入口。
:::

## 术语

| 术语       | 含义                                                       |
| -------- | -------------------------------------------------------- |
| wikitext | MediaWiki 风格的页面源码                                        |
| 解析快照     | 某份源码加上站点配置后的语义结果，对应 `WikitextDocument`                   |
| 渲染快照     | 完成插件、HAST 转换、清洗与整理后的结果，对应 `WikitextRenderDocument`       |
| 解析函数     | 宿主提供的 `resolveLink`、`resolveImage`、`resolveTemplate` 等回调 |
| 转换函数     | `prepareOptions.handlers` 中把自定义语义节点转换为 HAST 的函数          |
| 策略       | `prepareOptions.policy` 中的 URL、标签与类名规则                   |
| 文案       | `prepareOptions.labels`，所有用户可见占位与提示                      |

## 下一步

- [基本用法](/zh/guide/usage.md)：源码组件与显式管线。
- [服务端与框架](/zh/guide/server-rendering.md)：快照序列化、Next.js 与 hydration。
- [准备 `/hast`](/zh/api/prepare.md)：插件、解析函数、策略与快照恢复。
