- UI组件
- 移动开发
- 跨平台
【免费下载链接】gluestack-ui
React & React Native Components & Patterns (copy-paste components & patterns crafted with Tailwind CSS (NativeWind))
本文基于 gluestack-ui 官方文档仓库中的设计规格 AST-powered LLM documentation generation design,完整讲解该仓库如何为
llms.txt/llms-full.txt构建一条从 MDX 源文档到 LLM 友好文本的转换管线。读者将掌握unified+remark生态的 AST 处理思路、semantic-extractor插件的节点级语义转换策略,以及当前仓库中实际落地该目标的正则清洗实现与后续演进方向,可直接用于自己项目"文档喂给大模型"场景的工程化改造。
背景:为什么正则清洗 MDX 行不通
gluestack-ui 官方站点的文档以.mdx编写(例如 Button 组件文档),其中除了标准 Markdown,还混入了大量自定义 JSX 组件:交互式代码预览<CodePreviewer />、属性表格<Table />、标签页<Tabs />、插图组件<AnatomyImage />等。当这些文档要被转换成适合 LLM 读取的纯文本时,原设计规格明确指出两个核心痛点:
- 正则解析脆弱:用正则表达式匹配嵌套的 JSX、含反引号与花括号的模板字符串属性(如
code={...})极易失配,导致结构上下文丢失; - API 信息质量差:简单地把组件标签"剥掉"会连带丢失
variant、size、colorScheme这类 props 信息,而这些恰恰是 LLM 使用组件时最需要的内容。
因此,设计文档提出了一个明确的目标转向:用 AST(抽象语法树)解析替代正则清洗,构建"语义转换"管线,让输出的文本是"高信号、可检索、面向使用方式"的。
需要说明的是,设计文档面向的是未来改造;当前仓库中实际运行的是其前置版本——scripts/generate-llms-files.js,它用正则实现了一套功能完整的 MDX→Markdown 清洗器,并产出了 llms.txt 与 llms-full.txt。同一目录下还有后续的演进设计 2026-05-12-llms-txt-generation-rewrite-design.md,两者共同勾勒了从"正则"到"AST"的完整演进路径。下文将先讲清 AST 设计本身,再对照仓库现状给出实践依据。
目标与原则:Usage-First 与 Semantic Extraction
设计文档为本管线确立了三条原则,它们决定了 AST 插件里每一个节点的处理策略:
| 原则 | 含义 | 落地表现 |
|---|---|---|
| Usage-First(使用优先) | 优先保留 API props 与代码示例 | 代码块与 props 表格是最高优先级内容,不被裁剪 |
| Semantic Extraction(语义抽取) | 自定义组件应被"翻译"成描述性文本,而不是直接剥离 | <Button variant="outline" size="sm">→[Button: variant="outline", size="sm"] |
| Robustness(健壮性) | 用真正的 MDX 解析器处理嵌套组件与复杂属性 | 基于remark-mdx生成标准 AST,再逐节点处理 |
这三条原则的最终服务对象是 LLM:输出的文档必须让大模型"看一遍就知道怎么用",而不是让它去猜被删除的 JSX 里藏了什么信息。
架构总览:三段式 Semantic Transform Pipeline
设计文档给出的系统骨架是一条标准的unified处理管线,与 Markdown 生态中经典的"parse → transform → stringify"完全一致:
Raw .mdx 内容 │ remark-parse + remark-mdx ▼ remark AST(文档结构树) │ semantic-extractor 自定义插件(unist-util-visit 遍历) ▼ 转换后的 AST │ remark-stringify ▼ 高信号 Markdown 字符串(面向 LLM 上下文窗口)阶段 1:解析(Parsing)
- 工具:
remark-parse+remark-mdx; - 输入:原始
.mdx文件内容; - 输出:一棵标准
remarkAST,完整表达文档的标题层级、段落、列表、代码块以及 MDX JSX 节点。
remark-mdx的关键价值在于:JSX 不再是被"偷偷塞进 Markdown 里的字符串",而是成为 AST 中可程序化访问的节点(mdxJsxFlowElement等),这为后续"按节点类型精准处理"铺平了道路。
阶段 2:转换(Transformation)——semantic-extractor插件
这是整个设计的核心。自定义插件用unist-util-visit遍历 AST,对四类节点分别处理:
A.mdxJsxFlowElement(自定义组件)——语义转换
不再整体剥离,而是做三件事:
- Prop 抽取:读取节点
attributes,找出实际使用的 props,如variant、size、colorScheme; - 组件元数据生成:把组件渲染为一段紧凑文本,例如:
- 输入
<Button variant="outline" size="sm">; - 输出
[Button: variant="outline", size="sm"]。
- 输入
- 结构映射:对容器型组件(如
Tabs、Table),在文本输出中保留层级关系,展示它们"如何被组合",而不是压平成一行。
B.mdxJsxTextElement/mdxJsxText(代码抽取)
专门针对携带代码字符串的 JSX 属性(如code={...}):提取原始字符串、去掉外层引号,并提升为标准 Markdown 代码块输出。目的很明确——代码块是 LLM 最高可见度的"用法信号",必须用最标准的形态呈现。
C.code(Markdown 代码块)
原样保留,同时保留语言标识符(如jsx、bash),为 LLM 提供语言上下文。
D. 纯视觉 / 非用法元素
识别纯粹用于页面展示的组件(如<AnatomyImage />、不带code属性的<CodePreviewer />),直接删除,降低 token 噪音,让输出聚焦于"如何用"。
阶段 3:序列化(Serialization)
- 工具:
remark-stringify; - 输出:清洗干净、面向 LLM 上下文窗口优化的 Markdown 字符串。
依赖清单
设计文档明确列出的新增依赖:
unified:管线编排核心;remark-parse:Markdown→AST;remark-mdx:MDX/JSX→AST 节点;remark-stringify:AST→Markdown;unist-util-visit:AST 遍历工具。
建议文件结构
设计文档提议把管线拆成两个文件:
scripts/generate-llms-files.js:入口(编排器),负责扫描文档、驱动管线、写出llms.txt与llms-full.txt;scripts/lib/semantic-extractor.js:核心转换插件逻辑,即上述semantic-extractor的实现。
仓库现状对照:正则清洗器的真实实现
设计文档描述的是目标态;当前仓库中真实运行的正则版 scripts/generate-llms-files.js 其实已经实现了与 AST 方案几乎一一对应的"语义等价"功能。逐条对照如下:
| AST 设计方案 | 正则版实际实现 |
|---|---|
mdxJsxFlowElement语义转换 | stripVisualComponents()剥离<AnatomyImage/>、<Responsiveness/>等纯视觉组件;replaceTabs()把<Tabs>/<TabItem>按标签输出**label:**小节 |
mdxJsxTextElement代码抽取 | replaceCodePreviewer()与replaceCodeBlock()把<CodePreviewer code={...}/>、<CodeBlock code="..." language="..."/>转成带语言标识的 fenced 代码块 |
code原样保留 | 先用占位符保护```代码块,待所有 JSX 处理完后再恢复,避免嵌套转换误伤 |
| 删除视觉元素 | stripVisualComponents()内置了AnatomyImage、Responsiveness、ManualInstallationNote、GithubLink、StarterKitLink、KitchenSinkLink等清单 |
| 组件元数据文本 | 后续重写设计(见 2026-05-12-llms-txt-generation-rewrite-design.md)曾尝试[Component: Name: props]文本节点,但因"丢光有用内容"被弃用,改为优先提取<AdvancedComponentLLMGenerator mdxContent={...}>中已预结构化的干净 Markdown |
正则版最棘手的难点是<CodePreviewer code={...}>:codeprop 内含嵌套模板字符串,反引号套反引号,正则无法直接闭合。replaceCodePreviewer()采用的绕行策略是:定位code={后,寻找其后必然出现的argTypes=、reactLive=、importMap=等已知 props 来判定模板串结束位置,再找到整个标签的/>。这段代码恰恰印证了设计文档"正则脆弱、需要 AST"的核心论断——正则版只能用"已知后继 props"这种启发式技巧来弥补。
此外正则版还包含两个 AST 方案同样需要解决的细节:
- 页元数据抽取:
extractTitle()从内容首个# H1提取标题(剥离链接与加粗),失败时按目录名回退;extractDescription()取 H1 后第一段有效正文并截断至约 120 字符。 - 页面分类:
getCategory()依据路径首段映射home→Getting Started、components→Components、guides→Guides等类别,供llms.txt按规范分组输出。
从仓库可见的产物看,这套管线效果是实实在在的:llms.txt 以title: description规范格式列出了 Getting Started、Components、Guides、Hooks、Apps、MCP Server 等分类;llms-full.txt 则把每个组件页渲染成"标题 + URL + 清洗后 Markdown + 分隔线"的连续文本——例如 Button 页输出中,交互式<CodePreviewer>已被还原为带jsx语言标识的 fenced 代码块,{{variant}}、{{size}}这类 Handlebars 占位符也原样保留,npx gluestack-ui add button的安装命令与完整tva样式定义均完整可读。
与运行时 LLM 生成器的关系:AdvancedComponentLLMGenerator
仓库中还存在另一条"运行时 LLM 文档生成"路径:components/custom/component-llm-generator/advanced.tsx。这是一个 Client Component,接收componentName、componentPath、mdxContent与children,在useEffect中通过正则从mdxContent提取描述、Props 表、Features、CodePreviewer 示例与 Best Practices,拼装成一段结构化 Markdown(含## Description、## Props、## Usage Examples、## Best Practices、## For AI Assistants等章节),供用户一键复制给 AI 助手使用。
它与静态管线的关系是互补的:静态管线在构建期(yarn generate:llms,见 apps/website/package.json 中generate:llms脚本)批量产出全站llms.txt/llms-full.txt;而AdvancedComponentLLMGenerator是页面内按需生成单个组件的 LLM 摘要。后续重写设计(2026-05-12-llms-txt-generation-rewrite-design.md)明确提出把mdxContent作为"最高质量抽取路径"——因为它内部本身就是干净、预结构化的 Markdown,这正好是 AST 方案中"Semantic Extraction"思想的高阶体现。
成功标准与验收方法
设计文档为改造定义了三条可验证的成功标准,也适合作为读者自行实现同类管线的验收清单:
- 用法可见:
llms-full.txt中包含清晰的文本化组件用法,形如[Component: Name] with props: { ... }; - 无残缺 JSX:输出中不存在"剥到一半"的 HTML/JSX 残留(这正是正则方案最容易翻车的地方);
- API 模式显式化:
variant、size等用法模式即使不在标准代码块内,也必须在正文中被显式提及。
对照当前仓库,标准 2 与标准 3 已由 scripts/generate-llms-files.js 的cleanMDX()在正则层面基本满足;而标准 1 所设想的[Component: Name]元数据形态,恰好是后续重写设计中因"丢失有用内容"而被否定的中间方案——这一来一回,正好说明了为什么 AST 方案最终要把重点放在"保留代码与 props 表"而非"生成组件摘要"上。
实践要点:如何在其他项目复刻这条管线
若要在自己的文档站点落地同样的 LLM 文档管线,可按设计文档的架构逐步实施:
- 接入解析层:安装
unified、remark-parse、remark-mdx,把.mdx文本解析为 AST; - 编写
semantic-extractor插件:用unist-util-visit遍历,重点处理mdxJsxFlowElement(组件→语义文本 + 保留结构)、mdxJsxTextElement(code属性→代码块)、code(原样保留 + 语言标识)、纯视觉组件(删除); - 序列化与编排:用
remark-stringify输出,再由入口脚本按页面分组、生成llms.txt摘要(含title: description)与llms-full.txt全文(页面间用---分隔); - 纳入构建流程:参照仓库做法把生成脚本挂进
package.json的build流程,保证每次发布都产出最新版 LLM 文档(apps/website/package.json); - 用成功标准验收:重点检查"无 JSX 残留"与"API props 显式化"两项,可结合现有产物 llms.txt 与 llms-full.txt 做对拍验证。
结语
gluestack-ui 的这份设计文档给出了一个清晰的工程判断:当文档中充满自定义 JSX 组件时,"正则清洗"只是权宜之计,AST 语义抽取才是让文档对 LLM 真正"可读、可检索、可引用"的可靠路径。以unified+remark-mdx为底座、以semantic-extractor为语义核心、以remark-stringify收尾的三段式管线,配合"Usage-First"的原则与三条可量化验收标准,既是对当前正则实现(scripts/generate-llms-files.js)已知缺陷的系统性修复,也为任何想把技术文档"喂"给 AI 的开发团队提供了一套可以直接照搬的参考架构。
- UI组件
- 移动开发
- 跨平台
【免费下载链接】gluestack-ui
React & React Native Components & Patterns (copy-paste components & patterns crafted with Tailwind CSS (NativeWind))
相关推荐
用 LangChainGo 构建智能文档生成器:从 Go AST 解析到 LLM 驱动的自动化文档管线
用 LangChainGo 构建智能文档生成器:从 Go AST 解析到 LLM 驱动的自动化文档管线 本篇教程讲解如何使用 LangChainGo(模块路径
人工智能大模型AI AgentRAG后端如何搭建免费开源气象数据 API:Open-Meteo 部署与使用完整指南
如何搭建免费开源气象数据 API:Open Meteo 部署与使用完整指南 Open Meteo 是一个开源气象数据 API:无需注册、无需 API Key,一
后端API网关数据工程Haystack Extractors 组件深度指南:LLM 文档内容抽取、元数据生成、NER 命名实体识别与正则文本提取
Haystack Extractors 组件深度指南:LLM 文档内容抽取、元数据生成、NER 命名实体识别与正则文本提取 本篇技术指南以 Haystack 2
人工智能大模型RAGAI AgentNLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考