如何在VitePress等静态站点生成器的Markdown文件中渲染TypeScript类型或变量值?
如何在VitePress等静态站点生成器的Markdown文件中渲染TypeScript类型或变量值?
嘿,这个问题我之前也遇到过!手动同步文档和代码真的太麻烦了,尤其是Zod Schema或者TS类型这种经常变动的内容。下面给你几个在VitePress里实现自动渲染的方法,亲测好用:
方案1:用Vue组件动态解析Zod Schema(推荐用于结构化展示)
既然你的库已经用了Zod,我们可以直接利用Zod的API提取Schema的结构信息,然后用Vue组件渲染成可读性强的表格或列表,完全和代码同步。
步骤1:创建Schema渲染组件
在你的VitePress项目里新建一个components/SchemaRenderer.vue文件:
<script setup lang="ts"> // 直接导入你的库中的Schema import { userSchema } from '../../path-to-your-library/index.ts' // 提取Schema的字段、类型和约束信息 const schemaFields = Object.entries(userSchema.shape).map(([fieldName, fieldSchema]) => { const constraints: string[] = [] // 解析Zod的常见约束,可根据需求扩展 if (fieldSchema._def.minLength) { constraints.push(`最小长度:${fieldSchema._def.minLength.value}`) } if (fieldSchema._def.isRequired) { constraints.push('必填') } return { name: fieldName, type: fieldSchema._def.typeName, constraints: constraints.join(' | ') || '无' } }) </script> <template> <div class="schema-container"> <h3>📋 User Schema 定义</h3> <table class="schema-table"> <thead> <tr> <th>字段名</th> <th>类型</th> <th>约束规则</th> </tr> </thead> <tbody> <tr v-for="field in schemaFields" :key="field.name"> <td>{{ field.name }}</td> <td>{{ field.type }}</td> <td>{{ field.constraints }}</td> </tr> </tbody> </table> </div> </template> <style scoped> .schema-table { width: 100%; border-collapse: collapse; margin-top: 16px; } .schema-table th, .schema-table td { border: 1px solid #e5e7eb; padding: 8px 12px; text-align: left; } .schema-table th { background-color: #f9fafb; font-weight: 600; } </style>
步骤2:在Markdown中使用组件
直接在你的文档Markdown里引入这个组件就行:
<SchemaRenderer />
这样每次你更新库中的userSchema,文档里的内容会自动同步,完全不用手动复制!
方案2:构建时提取TS类型(适合展示编译时类型)
TS类型是编译时概念,没法直接在运行时读取,所以我们可以用工具在VitePress构建前解析TS文件,提取类型信息,再渲染到文档里。
步骤1:安装依赖
先装ts-morph(一个强大的TS代码解析工具)和ts-node(用来运行TS脚本):
npm install ts-morph ts-node --save-dev
步骤2:编写类型提取脚本
新建scripts/generate-type-docs.ts:
import { Project } from 'ts-morph' import fs from 'fs' import path from 'path' // 初始化TS项目 const project = new Project() // 导入你的库文件 const sourceFile = project.addSourceFileAtPath(path.resolve(__dirname, '../path-to-your-library/index.ts')) // 提取User类型的文本 const userTypeAlias = sourceFile.getTypeAlias('User') if (userTypeAlias) { const typeText = userTypeAlias.getType().getText() // 将类型信息写入JSON文件,供Vue组件读取 const outputPath = path.resolve(__dirname, '../docs/.vitepress/data/user-type.json') fs.mkdirSync(path.dirname(outputPath), { recursive: true }) fs.writeFileSync(outputPath, JSON.stringify({ typeText }, null, 2)) }
步骤3:修改构建脚本
在package.json里更新VitePress的构建命令,让它先运行提取脚本:
{ "scripts": { "docs:build": "ts-node ./scripts/generate-type-docs.ts && vitepress build docs", "docs:dev": "ts-node ./scripts/generate-type-docs.ts && vitepress dev docs" } }
步骤4:创建类型渲染组件
新建components/TypeRenderer.vue:
<script setup lang="ts"> // 导入预先生成的类型信息 import userTypeData from '../.vitepress/data/user-type.json' </script> <template> <div class="type-container"> <h3>🔤 User Type 定义</h3> <pre class="type-code"> <code class="language-typescript">{{ userTypeData.typeText }}</code> </pre> </div> </template> <style scoped> .type-code { background-color: #f9fafb; padding: 16px; border-radius: 6px; overflow-x: auto; } </style>
步骤5:在Markdown中使用组件
<TypeRenderer />
现在每次启动开发服务或构建文档时,都会自动提取最新的TS类型,确保文档和代码一致。
方案3:直接导入代码片段(适合展示原始代码)
如果只是想展示库中Schema或类型的原始代码,VitePress支持直接导入文件中的指定代码块,不用手动复制。
步骤1:给代码加标记
在你的库的index.ts里给需要展示的代码块加上区域标记:
// #region userSchema const userSchema = z .object({ username: z.string().min(1), }) .strict(); // #endregion // #region userType type User = z.infer<typeof userSchema>; // #endregion export { userSchema, type User }
步骤2:在Markdown中导入
用VitePress的代码导入语法,直接引入指定区域的代码:
```ts <<< @/path-to-your-library/index.ts#userSchema
<<< @/path-to-your-library/index.ts#userType
这种方式最简单,适合需要展示原始代码的场景,同样能保持和代码的同步。 备注:内容来源于stack exchange,提问作者baitendbidz
相关产品推荐
相关产品推荐

