跳到正文
本页目录

功能与运行时行为

Doctrine 在开发 SSR、生产预渲染和浏览器 hydration 中使用同一套路由模型与 React 外壳。两个 命令的生命周期不同,但渲染的是同一种页面模型。

MDX 优先

开发服务器

doctrine dev 会创建自定义 Vite 服务器。每次收到文档请求时,它加载当前 server entry、查找 归一化路由、import MDX 模块、渲染 HTML,再交给 Vite 转换后返回。

Watcher 处理两类相关源码:

  • MDX 的新增、修改与删除会更新 @amamo/mdx 记录。
  • meta.tsmeta.<locale>.ts 变化会让导航与图标 virtual module 失效,并触发 full reload。

Serve 模式允许相关文件依次保存时出现短暂导航不一致。新页面只有在最近的导航文件引用后才会 进入路由列表;生产构建则执行严格校验。

静态网站生成

doctrine build 会执行完整流水线:

  1. 校验输出安全性、配置、locale 和导航。
  2. 用 Vite 构建浏览器与 SSR environment。
  3. Import SSR entry 并列出文档路由。
  4. 预渲染每条路由和共享的 404.html
  5. 启用页面操作时,输出与路由对应的原始 MDX 源码。
  6. 移除 Vite 私有 manifest。
  7. 根据最终输出目录生成 Pagefind 索引。

每篇文档页面都包含 <html lang>、title、description、canonical URL、匹配的语言 alternate 和 共享资源。存在默认 locale 翻译时,Doctrine 还会输出 x-default alternate。

路由与导航

内容路径会成为路由 slug:

text
docs/index.mdx                  -> /
docs/guide/page.mdx             -> /guide/
docs/reference/config.mdx       -> /reference/config/
docs/reference/config.zh-CN.mdx -> /zh-CN/reference/config/

index.mdxpage.mdx 都代表所在目录,因此同一目录、同一 locale 不能同时使用两者。其他 basename 会变成带结尾斜杠的路由。

导航只来自就近元数据。每个条目只能命名直属页面或直属子目录;数组定义准确顺序、页面标题、 分组标题和可选图标。生产构建会拒绝遗漏、重复或不存在的引用。

页面条目也可以指向同目录的 .tsx 文件。Doctrine 只 import 最近语言导航文件明确列出的 TSX, 未列出的文件仍是普通组件,不会被当作页面解析。TSX 页面沿用导航标题和路由,但只放进共享的 顶部导航与页脚,不渲染文档侧栏、正文排版或本页目录。同一 locale 下,MDX 与 TSX 不能使用 相同的页面 basename。

TypeScript
export default {
  items: [{ page: 'landing', title: '落地页' }],
}
TSX
export default function LandingPage() {
  return <main>在这里构建任意 React 布局。</main>
}

Doctrine 默认的 MDX 链接组件会给根相对链接补上部署 base。外部 https://... 链接在新标签页 打开。注册自定义 a 组件会替换这套行为。

页面操作与原始 Markdown

默认情况下,每个 MDX 正文页都有 Copy Page 操作,其菜单还会提供 View as Markdown。 配置 githubUrl,且能够推导仓库内源码根目录或显式设置 githubSourceRoot 时,还会显示 Open in GitHub。GitHub 操作通过 blob/HEAD 指向当前 locale 的真实源文件,让 GitHub 解析到 仓库默认分支。因此,翻译路由会打开带 locale 后缀的源文件,而不是默认 locale 文档。

Doctrine 在开发环境提供同一份原始源码,并在生产构建中将其写入路由对应的 .md URL:

text
/                         -> /index.md
/index/                   -> /index/index.md
/guide/install/           -> /guide/install.md
/zh-CN/guide/install/     -> /zh-CN/guide/install.md

额外的 index 段用于避免站点根页与真实的 /index/ 文档争用同一个文件。

这里输出的是原始 MDX,不是从渲染后 HTML 还原的 Markdown,因此可以包含 frontmatter、ESM import、 JavaScript 表达式和 JSX。Copy Page 复制同一份源码,View as Markdown 则打开对应的 .md URL。

独立 TSX 页面不显示这些操作,也不会生成 .md 源码路由。设置 pageActions: false 可以在整个 站点关闭页面操作和 MDX 源码输出,但不会移除 Header 中独立的 GitHub 链接。

搜索

生产搜索会索引渲染后的 HTML,包括自定义 MDX 组件输出的文字。浏览器只在用户输入查询后加载 Pagefind,短暂等待后最多显示八条结果。⌘KCtrl+K 都能打开搜索。

开发环境不会写永久索引。第一次搜索请求根据当前 SSR 结果在内存中构建 Pagefind 文件。内容或 导航变化会让缓存失效,下一次搜索请求再重建。

多语言

默认 locale 没有路由前缀,其他 locale 使用编码后的前缀。只有另一个文档具有相同 slug 时, 语言按钮才会显示。

导航和页面元数据都不会跨 locale fallback;语言切换标签缺失时直接显示 locale code。

Doctrine 内置界面文案只区分两组:名称以 zh 开头的 locale 使用中文,其余使用英文。内容、 导航、网站元数据、路由前缀和 <html lang> 仍使用完整的配置 locale。

主题与自定义

主题控件把 lightdark 写入 localStorage。Head 中的内联脚本会在页面 body 渲染前应用 已保存选择;首次访问则使用操作系统偏好。

Doctrine 提供预编译界面 CSS,以及 BadgeCalloutCardCardGridCodeBlockFileTreeFileTreeFolderFileTreeFileInstallTabsLivePreviewStepStepsTabTabs。语义化的折叠内容、定义列表、图片说明、键盘输入、重点、引用和表格无需包装组件也会 获得完整样式。配置的 CSS 在默认样式之后加载;自定义组件映射在内置映射之后合并,并由 SSR 和 浏览器 hydration 共用。

内置能力与示例见 MDX 组件

Tailwind 是可选项。只有文档项目根 package.json 在 dependencies、dev dependencies 或 optional dependencies 中声明 tailwindcss 时,Doctrine 才启用对应 Vite 插件。

部署子路径

siteUrl 的 pathname 会成为 Vite 公开 base。Doctrine 把它应用到资源、默认 MDX 链接、语言 路由、Pagefind 结果、canonical URL 和 404 页资源,但不会嵌套输出目录。

信任边界

静态产物不会让源码失去执行能力。MDX 可以包含 ESM 和 JavaScript 表达式;被导航引用的 TSX 页面、doctrine.config.*、导航模块和自定义组件也都是可执行模块。它们可能在加载配置、打包、 SSR 或 hydration 时运行。只能构建你愿意授予构建机器与部署网站权限的可信源码。

内置 frontmatter schema 只校验可选字符串 description,它不是沙箱。编译器的详细边界见 @amamo/mdx 安全模型

copyright © 2026 白熱。