JavaScript is required

示例内容构建机制

relation-graph 官网的示例详情页不仅面向普通用户,也需要面向搜索引擎和大模型。为了让大模型直接通过示例 URL 读取到示例文章、文件树和源码内容,示例详情页在静态构建阶段会为免费示例注入源码快照。

本文说明 /examples/* 相关页面的路由、源码注入、增量构建和缓存机制。

路由模型

示例详情页使用平台路径作为静态 HTML 的变体维度:

路由 含义
/examples/<exampleId> 旧入口,按 React 示例渲染,并设置 canonical 到 /examples/<exampleId>/react
/examples/<exampleId>/react React 示例详情页。
/examples/<exampleId>/vue3 Vue3 示例详情页。
/examples/<exampleId>/vue2 Vue2 示例详情页。
/examples/<exampleId>/svelte Svelte 示例详情页。
/examples/<exampleId>/web-component HTML/Web Component 示例详情页。
/zh/examples/<exampleId>/... 中文 locale 对应页面。

旧的 ?lang=<platform> query 不再作为静态 HTML 变体依据。客户端遇到旧 URL 时会跳转到对应的平台路径,例如:

/zh/examples/basic-custom-node-and-minimap?lang=vue3

会跳转到:

/zh/examples/basic-custom-node-and-minimap/vue3

这样每个 locale + exampleId + platform 都有独立 HTML,大模型抓取 URL 时不会拿到错误平台的源码。

源码注入边界

构建阶段只为免费示例注入源码快照。免费示例的判断逻辑是:

!example.meta?.vip && !example.meta?.entVip

付费示例仍然会生成 platform 页面,但最终 HTML 中不会包含源码快照。用户点击源码区域时,仍然通过 source-code-v2/* 接口读取源码,由接口完成登录和权限校验。

免费示例的源码快照会在 Nuxt 生成 HTML 后注入到页面底部:

<script id="rg-example-source-snapshot" type="application/json">
  ...
</script>

这个 JSON 包含:

字段 说明
exampleId 示例 ID。
platform 平台名称,如 vue3
sourceRoot 源码所在目录。
mainFile 默认打开的源码文件。
filesTree 完整文件树,文件节点包含完整文本源码。
files 文件路径、大小和 hash 摘要列表。

前端源码面板打开时会优先读取这个内嵌快照。命中快照时,点击文件树不会请求源码接口;未命中快照时才回退到接口读取。这意味着:

示例类型 SSR HTML 是否含源码 点击文件树是否请求源码接口
免费示例 否,优先使用内嵌快照。
付费示例 是,由接口做权限校验。
非首屏 SPA 跳转且未加载目标 HTML 不一定 可能回退接口;平台切换使用完整页面跳转以尽量加载目标 HTML。

源码目录

构建脚本直接读取本机固定源码仓库:

platform 源码目录
react ../relation-graph-site-react/src/v3-examples/<exampleId>
vue3 ../relation-graph-site-vue3/src/v3-examples/<exampleId>
vue2 ../relation-graph-site-vue2/src/v3-examples/<exampleId>
svelte ../relation-graph-site-svelte/src/v3-examples/<exampleId>
web-component ../relation-graph-site-web-component/src/v3-examples/<exampleId>

免费示例任意平台源码目录缺失、不可读或没有可读取的文本源码时,构建会失败并输出具体 exampleId + platform + file 信息。

构建会跳过以下内容:

类型 说明
依赖和构建目录 node_modules.nuxt.outputdistbuildcoverage 等。
锁文件 package-lock.jsonpnpm-lock.yamlyarn.lockbun.lockb
二进制资源 图片、字体、音视频、压缩包、PDF、WASM 等。

文本源码文件必须完整注入,不会截断。为了避免意外把超大文本塞进 HTML,单文件和单快照有构建上限;超过上限时构建失败,而不是生成不完整源码。

构建模式

yarn generate:relation-graph 默认使用 changed 模式:

yarn generate:relation-graph

等价于:

RG_EXAMPLES_PRERENDER_MODE=changed yarn generate:relation-graph

支持的模式如下:

模式 行为 使用场景
full 重新生成所有示例详情页并刷新缓存。 首次启用机制、路由模板变化、缓存失效。
changed 默认模式。根据指纹只生成变化过的示例详情页,其余从缓存恢复。 日常构建。
skip 不生成示例详情页,只从缓存恢复。缓存不安全时直接失败。 明确确认 /examples/* 无关变更时的快速构建。

首次启用或缓存缺失时需要运行:

RG_EXAMPLES_PRERENDER_MODE=full yarn generate:relation-graph

之后日常执行:

yarn generate:relation-graph

指纹规则

changed 模式会为每个示例详情 route 计算 fingerprint。影响 fingerprint 的内容包括:

内容 影响范围
locale 中文和英文页面分别计算。
exampleIdplatform 每个平台页面分别计算。
示例 meta、标题、描述 示例目录数据变更会触发重建。
当前 locale 的示例 markdown 示例文章变化会触发对应 locale 重建。
免费示例源码文件路径和内容 hash 源码变化会触发对应 platform 重建。
示例详情页模板、源码面板、platform 工具、站点配置 这些公共模板变化时,changed 会退化为 full。
扫描器版本 扫描规则升级时会退化为 full。

付费示例不会把源码 hash 纳入 fingerprint,因为构建阶段不会读取或注入付费源码。

缓存结构

示例静态构建缓存位于:

.cache/relation-graph-example-prerender/

主要内容:

路径 说明
manifest.json 记录 route fingerprint、模板 hash、源码快照 hash 和更新时间。
routes/ 缓存每个示例详情 route 目录下的 index.html_payload.json_payload.json 保存 Nuxt payload,其中包含示例文章等 SSR 数据。
assets/ 缓存示例 HTML 引用到的旧 _nuxt 资源。
work/current-plan.json 当前构建计划。
work/source-snapshots/ 当前构建生成的免费示例源码快照。

changed 或 skip 模式会把未变化示例 route 的 index.html_payload.jsonroutes/ 恢复到:

apps/relation-graph-site/.output/public

同时会把缓存中的 _nuxt 资源合并回输出目录。输出目录短期存在多版本 _nuxt 文件是预期行为,因为复用旧 HTML 时必须保留旧 HTML 引用的 hash 资源。

构建流程

yarn generate:relation-graph 实际执行三段流程:

1. ai-tools/example-prerender/prepare.mjs
   扫描示例源码,计算 fingerprint,生成 current-plan.json。

2. nuxi generate apps/relation-graph-site
   只 prerender 当前计划允许的示例详情路由,以及其它站点页面。

3. ai-tools/example-prerender/finish.mjs
   恢复未变化示例页的 HTML 和 payload,注入免费示例源码快照,缓存新 HTML、payload 和 _nuxt 资源,更新 manifest。

Nuxt prerender 的 crawlLinks 仍然开启,但示例详情页会通过 ignore 规则限制:只有构建计划里的无 query route 可以被生成。带 fromGroupIdlang 等 query 的示例详情 URL 不会写入静态 HTML。

常用命令

# 日常构建:默认 changed
yarn generate:relation-graph

# 强制刷新所有示例详情页和缓存
RG_EXAMPLES_PRERENDER_MODE=full yarn generate:relation-graph

# 明确跳过示例详情页生成,仅复用缓存
RG_EXAMPLES_PRERENDER_MODE=skip yarn generate:relation-graph

# 只生成 Nuxt 静态站点,不执行示例缓存流程。仅用于排查问题。
yarn generate:relation-graph:nuxt

故障处理

问题 处理方式
skip 模式失败 说明缓存不完整或模板 hash 不匹配,改用 full
免费示例源码目录缺失 补齐对应平台源码目录,或从示例目录中移除该示例。
文本源码过大 拆分源码文件,或确认是否应作为二进制/生成产物被排除。
付费示例 HTML 出现源码 这是严重问题,应立即检查免费/付费判断和注入脚本。
示例文章先显示后变成 Markdown File Not Found 通常说明对应 route 的 _payload.json 没有被恢复到 .output/public,浏览器 hydration 后回退请求静态站不存在的 /api/example-markdown-content。需要刷新示例缓存。
页面引用旧 _nuxt 资源 404 确认 .cache/relation-graph-example-prerender/assets/ 已合并到 .output/public/_nuxt