ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Astryx Docsite 数据管道全解析:从 Monorepo 到类型化注册表的自动化文档站

Astryx Docsite 数据管道全解析:从 Monorepo 到类型化注册表的自动化文档站 Astryx Docsite 数据管道全解析从 Monorepo 到类型化注册表的自动化文档站【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx本文以 Astryx 开源设计系统的官方文档站apps/docsite为对象深入讲解其构建期数据管道build-time data pipeline架构如何从 monorepo 中的package.json、.doc.mjs组件文档、CLI 模板与 Markdown 内容中自动提取数据生成类型化 TypeScript 注册表并驱动latest已发布版本与canary主干 WIP 版本两套内容版本。读完本文你将掌握该文档站的完整工作流、添加主题/包/博客的标准操作以及数据管道各环节的源码级实现原理可直接据此为 Astryx 扩展文档内容或复刻同类自动化文档站。文档站定位一个不硬编码任何目录的 OSS 文档站apps/docsite是 Astryx 的开源文档站使用 Next.js 与 StyleX 构建承载组件目录、包详情页、模板画廊、主题展示、Craft 落地页与博客。它的核心设计原则是文档站从不硬编码包列表、组件目录或主题映射所有数据都经由构建期数据管道从 monorepo 提取并写入src/generated/下的类型化 TypeScript 注册表页面只负责消费这些注册表渲染。这意味着包packages/*、CLI 模板、.doc.mjs组件文档或主题包的任何增删改都会在重新构建后自动反映到站点上无需手改任何页面代码。快速启动在仓库根目录执行pnpm install # from repo root pnpm build # build all packages (themes need built exports) cd apps/docsite pnpm generate # extract data from the monorepo into src/generated/ pnpm dev # start the dev serverpnpm dev与pnpm build都会通过predev/prebuild自动先执行generate。查看 apps/docsite/package.json 可以发现generate实际是一串流水线而不仅是generate-data.mjsgenerate: node scripts/check-workspace-build.mjs pnpm build:theme node scripts/generate-data.mjs node scripts/generate-scope.mjs node scripts/generate-playground-types.mjs node scripts/copy-vendor.mjs, dev: pnpm generate next dev --webpack, build: pnpm generate next build --webpack node scripts/check-template-gallery-bundle.mjs即先校验工作区已构建 → 编译站点自身主题 CSS → 运行数据管道 → 生成作用域与 playground 类型 → 拷贝 vendor 资源最后才启动 Next.js 开发服务器--webpack因为站点固定使用自定义 babel 配置以支持 StyleX。数据管道九个注册表如何生成管道入口是 apps/docsite/scripts/generate-data.mjs它扫描 monorepo 并产出多个注册表文件到apps/docsite/src/generated/该目录被 gitignore属于构建产物注册表数据来源包含内容packageRegistry.tspackages/*/package.json每个已发布包的名称、版本、描述、READMEcomponentRegistry.tsCore CLI 配置的集成.doc.mjs文件各包的 Props、用法文档、hooks、分组componentPreviewRegistry.ts来自相同包的组件共享 Properties 预览所需的运行时导出blockRegistry.tsCLI 集成模板 block带元数据的展示与示例 blocktemplateRegistry.tsCLItemplates/pages/页面级模板如 dashboard、settingsdocsRegistry.tsCLIdocs/长文指南与基础主题blogRegistry.tssrc/content/blog/posts/人工撰写的博客文章frontmatter 校验themeRegistry.ts已安装的astryxdesign/theme-*包以包名为 key 的内建主题对象showcaseRegistry.ts带isShowcase的 block拷贝的 showcase 源码文件exampleRegistry.ts带exampleFor的 block每个组件对应的示例 block包发现Package DiscoverydiscoverPackageDirs()通过expandWorkspaceDirs(CONTENT_ROOT)展开pnpm-workspace.yaml的packages:块仅保留packages/*前缀目录跳过apps/*与internal/*并要求存在package.json。随后generatePackageRegistry()对每个包做三关过滤private 包默认跳过除非是 canary 目标的canaryOnly包未安装到 docsite包的name必须在 docsite 的dependencies/devDependencies中出现对应测试 only includes packages listed in docsite dependencies读取README.md与CHANGELOG.md内容并推导displayName如theme-butter→Theme: Butter。generatePackageStyles()还会扫描 canary 组件包的exports中所有.css子路径汇总生成package-styles.css聚合导入。组件提取Component ExtractiongenerateComponentRegistry()只处理astryxdesign/core与 CLI 配置的集成包见下文astryx.config.mjs在每包的src/下递归查找*.doc.mjs跳过utils、__tests__、node_modules。每个.doc.mjs文件通过动态import()加载后归一化为ComponentEntry覆盖四类形态独立组件直接导出name、props、usage、theming、playground复合组件family parentcomponents[]中的子项被展开为独立条目并继承父文档的group/category/keywords但不继承父文档的 usage 散文测试 extracted sub-components do not inherit parent usage prose 验证了这一点独立子文档subComponentOf以自身文件为准缺失字段回退到目录主文档Hook 文档params/returns识别use前缀或params数组单独产出带params/returns的条目。提取过程中还有两个强约束值得注意displayName必填requireDisplayName()会抛错要求每个.doc.mjs显式声明displayName缺失时可用node apps/docsite/scripts/backfill-display-name.mjs补齐类型引用解析通过buildTypeDefinitionIndex/collectPropTypeRefs将props/params/returns中引用的具名类型如SearchSourceT、ToastOptions记录为typeRefs并把声明源码附加到条目的typeDefs让文档表格可按需渲染非原始类型。组件名在全部包之间要求全局唯一重复会直接抛错且最终写入的注册表文件包含完整的PropDoc、UsageDoc、ThemingDoc、HookParamDoc等接口定义页面代码可直接获得类型提示。Block、模板与文档注册表generateBlockRegistry()扫描 CLI 的assets/templates/blocks/下每个.doc.mjs要求同名.tsx存在用正则提取isShowcase、aspectRatio支持16/9分数写法不 eval、componentsUsed、exampleFor、alsoExampleFor等元数据并读取 TSX 源码用于实时渲染。isShowcase: true的 block 必须同时声明exampleFor否则构建失败。generateTemplateRegistry()读取 CLIassets/templates/pages/dir/template.doc.mjspage.tsx跳过scaffold类型模板产出templateRegistry.ts与剔除源码后的templateMetadataRegistry.ts。generateDocsRegistry()读取 CLIassets/docs/*.doc.mjs跳过翻译变体.doc.zh.、.doc.dense.并在非 canary 目标下排除shadcn-compatibility主题。generateThemeRegistry()为每个astryxdesign/theme-*生成import {slugTheme} from pkg/built形式的themeObjects映射由于/built对象只含 token还会从包的完整导出中提取components组件覆盖如 display 字体重组成themeObjectsFull供主题编辑器/playground 运行时重建使用并同步生成themes.css聚合样式文件。generateShowcaseRegistry()/generateExampleRegistry()把 block 的 TSX 源码拷贝进src/generated/showcases|examples/并以懒加载() import(...)注册实现即写即渲染若 block 引用了 docsite 未安装的包如 canary-only 的astryxdesign/lab则跳过渲染预览但保留源码展示。generateBlogRegistry()复用src/lib/blog/posts.mjs的discoverPosts做发现与校验并扫描public/blog/**生成blogDarkImages暗色变体清单。最后调用generateShadcnRegistryForTarget()生成 ShadCN 注册表并通过checkShadcnRouteLock()与internal/shadcn-registry/routes.lock.json比对防止公开路由被意外改动。铁律The Rule所有数据必须来自管道。绝不在页面代码中硬编码包名、组件列表或主题对象。需要 monorepo 数据时先扩展generate-data.mjs产出新注册表再由页面消费。对应的三条禁令页面文件不得import {fooTheme} from astryxdesign/theme-foo/built应使用生成注册表的themeObjects不得手写组件名数组应使用componentRegistry不得写if (pkg astryxdesign/core)之类的包名开关让管道来分类。版本化内容latest 与 canary文档站只部署一份代码源自main但数据管道可根据构建target从两个不同来源读取包文档与 npm 的两个 dist-tag 一一对应目标npm dist-tag包文档来源部署位置latestlatest最近一次已发布的 npm 版本生产环境astryx.atmeta.comcanarycanary实时 monorepomainWIPcanary 站点 每个 PR 预览目标值由 Vercel 的VERCEL_ENV推导生产部署为latest预览部署main的 canary 站点与所有 PR 预览与本地开发均为canary。源码实现resolve-content-root.mjsapps/docsite/scripts/resolve-content-root.mjs 是目标 → 文件系统根目录的唯一映射点getTarget()环境变量DOCSITE_TARGETlatest|canary显式优先否则按VERCEL_ENV production ? latest : canary推导canarycontentRoot直接指向仓库根REPO_ROOT读取实时工作区latest先用npm view astryxdesign/corelatest version实时取最新发布版本然后对每个可发布的astryxdesign/*依赖执行npm pack下载其已发布 tarball并解包到.content-cache/npm-version/并写入一份合成pnpm-workspace.yaml声明packages/*与packages/themes/*使布局镜像 monorepo从而让generate-data.mjs的工作区发现逻辑原样复用。缓存以.stamp文件含版本与包清单的v2:签名做失效判断避免重复下载。注意latestPublishablePackages()会排除private与astryx.canaryOnly的包例如astryxdesign/charts、astryxdesign/lab只发 canary没有稳定版本可文档化——这与.github/workflows/release.yml的稳定发布判定保持一致保证生产站点文档化的就是稳定发布集合。关键点只有被文档化的数据是按版本固定的。CLI 模板演示showcases、examples、blocks、pages、长文文档是实时渲染的 React 组件始终从工作区内置的astryxdesign/core解析因为若将其固定到旧版本会让过期演示调用已不存在的 API破坏渲染与类型检查。⚠️ 贡献者须知库的改动不会立刻出现在生产站点生产站点astryx.atmeta.com文档化的是最近一次已发布的版本。如果你新增组件、修改 prop 或更新文档并合入main这些改动在下次发版到 npm 之前不会出现在生产站点。要在已部署站点看到改动请使用canary 站点或任意PR 预览两者都读取main或页脚中的 Canary docs 链接canary banner 上会链回生产站点。本地开发不受影响。pnpm dev没有VERCEL_ENV默认走canary读取实时工作区本地改动如常可见。若要本地预览latest视图用DOCSITE_TARGETlatest运行管道需要联网拉取已发布 tarballcd apps/docsite DOCSITE_TARGETlatest pnpm generate添加一个新主题在packages/themes/name/下创建主题包在 apps/docsite/package.json 的dependencies中添加astryxdesign/theme-name: *在src/app/globals.css中添加import astryxdesign/theme-name/theme.css实际上generateThemeRegistry()会自动把主题包聚合写入themes.css新主题也会一并进入该聚合文件加载主题字体见下运行pnpm generate主题会自动出现在themeRegistry.ts、packageRegistry.ts、侧边栏、Craft 页与包详情页。只将公开非 private主题包加入 docsite。字体加载主题按名称引用字体但不打包字体文件——若字体未加载会静默回退到系统字体。docsite 通过 apps/docsite/src/app/layout.tsx 中单个link标签从 Google Fonts 加载全部自定义字体。添加新主题时检查其 README 的## Fonts一节声明的字体族将缺失字体族追加进该 URL 即可。当前站点已聚合 Albert Sans、Crimson Text、DM Sans、Figtree、Fraunces、Fustat、JetBrains Mono、Manufacturing Consent、Montserrat、Outfit、PT Serif、Playwrite US Trad、Poppins、Sarina、UnifrakturMaguntia 等字族。之所以不用next/font/google是因为该 app 固定使用自定义babel.config.js支撑 StyleX与 Next.js 的 SWC 字体加载器互斥布局文件注释明确记载了这一冲突因此走共享link是Good路径。添加一个新包在packages/name/下创建包在 docsite 的package.json中添加astryxdesign/name: *依赖对于 canary-only 组件包在包的package.json中设置astryx.canaryOnly: true添加astryx.integration.mjs声明components: ./src并将该文件纳入包的files在 apps/docsite/astryx.config.mjs 中登记该包可选的 showcase block 也放在包内并通过集成的templates字段暴露目录docsite 通过 CLI 模板 API 获取它们。运行pnpm generate。包会自动出现在侧边栏、库libraries区块并获得独立的/docs/name详情页若含.doc.mjs其组件也会被提取进componentRegistry.ts。canary-only 的包与组件仅在 canary 构建中出现并携带 flask烧瓶图标标记。当前 astryx.config.mjs 登记的 canary 集成为astryxdesign/lab、astryxdesign/charts、astryxdesign/richtext、astryxdesign/vega。canary-only 组件使用既有的isReady: false状态在 canary 站点按所属包分组且只在包分类级别显示一个 flask 标记而非每个组件一个。添加一篇博客文章博客位于/blog索引与/blog/slug详情页。文章是人工撰写的 Markdown YAML frontmatter存放在apps/docsite/src/content/blog/posts/。添加一篇文章几乎等同于放下一个文件——发现、校验与排序全自动。完整指南见 apps/docsite/src/content/blog/README.md核心步骤如下创建apps/docsite/src/content/blog/posts/slug.md文件名即 URL slug必须携带title、description、date、type、authors、tags等 frontmatter若你是新作者先在apps/docsite/src/content/blog/authors.ts注册作者 keyGitHub 作者的 avatar/主页由 handle 自动推导无需构建期抓取运行pnpm generate pnpm test pnpm typecheck再用pnpm dev预览。必填 frontmatter 在构建期被校验draft: true的文章会被排除出生产输出本地开发与 canary 预览仍会渲染。frontmatter 的字段约束type枚举为update/guide/design/story/perspective/engineeringtags限 1–4 个可选updatedAt/dek/coverImage/coverAlt/releasePackage/relatedDocs与暗色图片变体机制public/blog/slug/pipeline.dark.png通过blogDarkImages清单在构建期判定跟随站点主题切换而非仅 OS 偏好都在该 README 中有完整说明。项目结构与命令apps/docsite/ ├── scripts/ │ ├── generate-data.mjs # 数据管道 │ ├── resolve-content-root.mjs # latest/canary 内容根解析 │ ├── generate-shadcn-registry.mjs # ShadCN 注册表 │ └── ... # 其他辅助脚本 ├── src/ │ ├── generated/ # gitignored — 管道输出 │ ├── app/ │ │ ├── globals.css # CSS 导入reset、astryx base、主题样式表 │ │ ├── layout.tsx # 根布局含 Google Fonts link │ │ ├── providers.tsx # 主题 客户端 providers │ │ ├── (docs)/ # 主文档路由components、packages、docs │ │ ├── blog/ # 博客索引 文章详情无侧边栏 │ │ └── craft/ # Craft 落地页templates、themes、showcases │ ├── components/ # 共享 UI 组件 │ ├── content/blog/ # 博客文章MD frontmatter authors.ts │ └── lib/blog/ # 博客发现、校验与类型 ├── package.json └── .gitignore # 排除 src/generated/命令作用pnpm generate运行数据管道pnpm dev启动 Next.js 开发服务器自动先生成pnpm build生产构建自动先生成pnpm typecheck运行tsc --noEmitpnpm test运行 vitestpnpm test:watch以 watch 模式运行 vitest测试保障注册表内容即契约测试集中在 apps/docsite/src/tests/data-extraction.test.ts运行前必须先pnpm generate因为它直接从src/generated/导入。测试覆盖了本文所述的全部注册表形成可自动验证的契约packageRegistry必须发现 core/cli/各主题与 canary 集成包且不得包含未安装、private 或非集成包每个包字段完整、README/CHANGELOG 内容非空componentRegistrycore 组件数量超过 100astryxdesign/core全部isReady而四个集成包全部!isReadyTable/Dialog/Chat 等复合组件正确展开为子组件并共享父级 group 与目录子组件拥有独立描述且不继承父文档 usage 散文Button 的labelprop 为必填stringusage 含bestPractices≥3与anatomy≥2theming 目标类名为astryx-button组件路由名全局唯一blockRegistryblock 数量 100、showcase 20、宽屏16:9与标准4:3比例均被正确解析、每个 showcase 声明组件归属且源码含export default function、通过 CLI 集成发现的 Charts showcase 元数据aspectRatio: 1.6、sourcePackage: astryxdesign/charts正确templateRegistry / docsRegistry / themeRegistry / showcaseRegistry / exampleRegistry模板元数据剔除source、博客类型与标签收集、showcase 与示例拷贝均被验证。从源码结构可以推断这套管道产出 → 测试锁定 → 页面只消费的机制保证了文档站内容与 monorepo 的真实状态始终一致新增组件/主题/包/文章不需要改动任何页面代码只需跑一次pnpm generate而latest/canary双目标让生产站点稳定文档化已发布版本同时让 canary 与 PR 预览即时呈现主干进展。这正是 Astryx 文档站agent ready特性的基础设施——所有数据对 Agent 与人类读者而言都是机器可读、类型安全且可精确检索的。【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表