服务端与框架
解析与准备都不依赖 React,可以在服务端、构建期或 Worker 中完成。客户端只加载 react-wikitext/view,接收并恢复渲染快照。
两种部署方式
第二种方式把解析成本留在服务端;客户端不再加载 wikiparser-node。
服务端准备
restoreWikitextRenderDocument 会重新校验结构版本、根节点、HAST 结构与节点预算,并重新执行最终清洗。它不信任任意第三方 HAST;只恢复来自可信服务端或可信缓存的快照。
Note
快照同时包含语义树、HAST 与源码,体积明显大于纯 HTML。大文档应按页或按块准备,并评估传输预算。
Next.js App Router
根入口与 /view 在模块加载时创建 Context,并使用 React Hook,因此只能在客户端组件中运行。这两个入口的产物顶部带有 "use client" 指令,宿主不需要额外建立边界;服务端只使用 /parse、/hast。
- 服务端准备阶段只调用
/parse与/hast;这两个入口不加载 React。 - 客户端组件只负责恢复与渲染,不重新解析。
- 根入口与
/view带"use client",Next.js 会把它们视为客户端边界:可以在 Server Component 中直接渲染,但解析随之发生在客户端。需要服务端解析时,按上面的页面组件先准备快照。 - 在其他 SSR 环境中,可以用
renderToStaticMarkup渲染WikitextView,再让客户端用同一份快照 hydrate。
Vite 与其他 SSR
普通 SSR 的思路相同:服务端准备快照,把它作为页面数据发送给客户端,客户端用 /view 恢复并挂载。
- 内联 JSON 时转义
<,避免</script>提前结束脚本。 - 如果页面要由搜索引擎直接读取正文,可以在服务端渲染
WikitextView;此时客户端必须用同一份快照、同一棵树 hydrate。
Hydration 与锚点
headingIdStrategy: "instance"使用useId生成实例前缀,服务端与客户端渲染同一棵树时保持一致。- 如果服务端与客户端结构不同,或同一页有多个实例,显式传入
idPrefix固定前缀。 - 需要与宿主约定裸锚点(例如已有
#Section链接)时,使用headingIdStrategy: "mediawiki";它假设页面只有一个实例。 headingIdStrategy: "none"不写 id,也不生成目录链接,适合不需要锚点的嵌入式展示。
缓存
渲染快照可以缓存,但键必须覆盖所有影响输出的输入:
AST_SCHEMA_VERSION、RENDER_SCHEMA_VERSION与解析器版本。- 源码与
pageName。 - 站点配置(
config)。 prepareOptions:解析函数、插件、policy、labels、headingIdStrategy与handlers。
恢复函数会拒绝版本不匹配的快照;升级库或解析器时应让缓存整体失效。解析结果的缓存策略见性能与预算。