Slidev 自定义 Mermaid 渲染器通过 setup/mermaid-renderer.ts 接入第三方 Mermaid 渲染库【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidev在 Slidev 中mermaid代码块默认由内置的 mermaid 库渲染。当你希望使用beautiful-mermaid等第三方渲染库来改变图表的视觉风格时只需在项目中新增一个setup/mermaid-renderer.ts文件用slidev/types提供的defineMermaidRendererSetup导出一个渲染函数即可。本文完整讲解该配置项的用法、背后的类型定义以及 Slidev 从 Markdown 代码块到 SVG 输出的整条渲染链路读完你既能照做配置也能理解自定义渲染器在何时被调用、返回什么、失败时如何回退到内置渲染。一、配置步骤两步接入第三方 Mermaid 库以下两步完整来自官方文档 docs/custom/config-mermaid-renderer.md第 1 步安装你想用的 Mermaid 渲染库例如npm install beautiful-mermaid第 2 步在项目根目录创建./setup/mermaid-renderer.ts内容如下// setup/mermaid-renderer.ts import { defineMermaidRendererSetup } from slidev/types // example. https://github.com/lukilabs/beautiful-mermaid?tabreadme-ov-file#readme import { renderMermaid } from beautiful-mermaid export default defineMermaidRendererSetup(() { return (code, _options) renderMermaid(code) })官方文档对这一设置的说明是该配置让你可以使用第三方 Mermaid 库只需要把示例中的renderMermaid()部分替换成你所用库的渲染函数即可。该配置仅作用于客户端client 端属于 Slidev 的 setup 文件体系之一。二、渲染链路你的自定义渲染函数在哪个环节被调用要理解mermaid-renderer.ts生效的时机需要看 Slidev 处理 mermaid 代码块的完整链路。整个流程横跨构建期Node 侧与运行期浏览器侧构建期代码块转换。packages/slidev/node/syntax/codeblock/mermaid.ts 中的代码块转换器匹配 开头的围栏代码块正则^mermaid\s*({[^\n]*})?还支持在 info string 里附加一个 options 对象字面量把原始 mermaid 文本用lz-string的compressToBase64压缩后转写为 组件调用export default defineCodeblockTransformer(async ({ info, code }) { const match info.match(RE_MERMAID) if (!match) return const [, options] match const optionsProp options ? v-bind${options} : const encoded lz.compressToBase64(code.trim()) return Mermaid ${optionsProp} code-lz${encoded} / })也就是说压缩只是为了让 mermaid 源码不出现在 Vue 组件的属性里原始文本在浏览器端再解压。运行期Mermaid 组件触发渲染。packages/client/builtin/Mermaid.vue 在watchEffect中调用renderMermaid(props.codeLz, options)其中的 options 由两部分组成当前主题暗色模式下为theme: dark以及代码块头传入的属性如scale、theme等来自第一步的v-bind。渲染得到的 SVG 字符串被写入ShadowRoot组件若抛出异常组件会显示一段红色边框的错误信息。运行期核心自定义渲染器优先内置 mermaid 兜底。关键实现在 packages/client/modules/mermaid.tsexport async function renderMermaid(lzEncoded: string, options: any) { containerElement ?? document.getElementById(mermaid-rendering-container)! const key lzEncoded JSON.stringify(options) const _cache cache.get(key) if (_cache) return _cache const code lz.decompressFromBase64(lzEncoded) // custom renderer for (const setup of mermaidRenderers) { const renderer await setup() if (renderer) { const svg await renderer(code, options) cache.set(key, svg) return svg } } // fallback: existing mermaid mermaid.initialize({ startOnLoad: false, ...clearUndefined(await setupMermaid() || {}), ...clearUndefined(options), }) const id makeId() const { svg } await mermaid.render(id, code, containerElement) cache.set(key, svg) return svg }从源码可以看出三个关键行为自定义渲染器优先mermaidRenderers来自虚拟模块#slidev/setups/mermaid-renderer循环中第一个返回了渲染函数的 setup 会被立即使用——你的第三方库渲染结果直接作为 SVG 字符串返回内置 mermaid 是兜底只有当所有 setup 都没有返回有效渲染函数时才会走mermaid.render此时会合并你在setup/mermaid.ts中通过defineMermaidSetup配置的MermaidConfig与代码块的 options结果有缓存以「压缩码 options 的 JSON」为键缓存 SVG 字符串相同图表在同一次会话中不会重复渲染。三、API 类型定义MermaidRendererSetup 与 MermaidRenderFndefineMermaidRendererSetup及相关类型定义在 packages/types/src/setups.ts 中export type MermaidSetup () AwaitablePartialMermaidConfig | void export type MermaidRenderFn (code: string, options: Recordstring, any) Awaitablestring export type MermaidRendererSetup () AwaitableMermaidRenderFn | void // ... export const defineMermaidRendererSetup defineSetupMermaidRendererSetup由此可以精确描述你的 setup 需要满足的契约层级签名说明setup 函数() AwaitableMermaidRenderFn \| void可以异步初始化如预加载第三方库资源最终返回一个渲染函数返回void表示不参与渲染渲染函数(code: string, options: Recordstring, any) Awaitablestring接收解压后的原始 mermaid 文本与 options 对象必须返回或 Promise 返回一段SVG 字符串其中code参数是解压后的 mermaid 源码你不必关心lz-stringoptions对象包含theme如dark以及代码块头附加的属性例如 中的字段见 [docs/features/mermaid.md](https://link.gitcode.com/i/a9d12620b16e9587f0cacb6c84da8073) 中对 options 语法的说明。defineSetup本身只是一个返回入参的标识函数见同文件 L108-L110 的function defineSetup (fn: Fn) { return fn }其作用是让 IDE 获得完整的类型推导。客户端虚拟模块的类型声明在 packages/types/client.d.ts 中declare module #slidev/setups/mermaid-renderer { import type { MermaidRendererSetup } from slidev/types const setups: MermaidRendererSetup[] export default setups }四、发现机制虚拟模块如何找到你的 setup 文件packages/client/modules/mermaid.ts中导入的#slidev/setups/mermaid-renderer是一个 Vite 虚拟模块其生成逻辑在 packages/slidev/node/virtual/setups.tsfunction createSetupTemplate(name: string): VirtualModuleTemplate { const id /slidev/setups/${name} return { id, getContent({ roots }) { const imports: string[] [] const globs roots.map((root) { const glob join(root, setup/${name}.{ts,js,mts,mjs}) // ... }) return ${imports.join(\n)}\n\nexport default [${globs.join(, )}].filter(Boolean) }, } } // setups const setupModules [shiki, code-runners, monaco, mermaid, mermaid-renderer, main, root, routes, shortcuts, context-menu]从这段源码结构看Slidev 会按你的每个项目根目录去匹配 globsetup/mermaid-renderer.{ts,js,mts,mjs}。这意味着文件名必须严格是mermaid-renderer扩展名支持ts / js / mts / mjs每个匹配结果经filter(Boolean)过滤因此没有创建该文件时模块导出空数组渲染直接落入内置 mermaid 分支——这也是为什么该功能可以完全按需启用不影响未配置的项目虚拟模块默认导出一个数组modules/mermaid.ts中的for (const setup of mermaidRenderers)逐个尝试第一个返回渲染函数的生效。仓库中的单元测试 test/mermaid-renderer.test.ts 验证了这条注册链路确认/slidev/setups/mermaid-renderer已在templateSetups中注册且生成的模块内容包含对setup/mermaid-renderer的 glob 导入与filter(Boolean)兜底逻辑。五、与 setup/mermaid.ts 的分工别把两个配置搞混Slidev 有两个名称相近的 mermaid 配置职责完全不同setup/mermaid.tsdefineMermaidSetup返回PartialMermaidConfig用于配置内置mermaid 库的初始化选项主题、布局等由 packages/client/setup/mermaid.ts 汇总后传给mermaid.initialize。它只在「兜底」路径上起作用setup/mermaid-renderer.tsdefineMermaidRendererSetup返回一个完全接管渲染过程的函数渲染函数返回的 SVG 直接呈现内置 mermaid 不再参与。两者可共存一旦自定义渲染器返回了 SVGsetup/mermaid.ts的配置在本次渲染中就不会被使用。如果你的目标只是调主题或布局参数用setup/mermaid.ts更轻量只有需要更换整个渲染引擎如换一种视觉风格、接入带自定义模板的渲染库时才需要setup/mermaid-renderer.ts。六、实践要点与常见排查渲染函数必须返回 SVG 字符串或返回它的 Promise。返回void/undefined会被视为「未接管」Slidev 会继续尝试下一个 setup 或回落到内置 mermaid返回值可以是异步的Awaitablestring允许你在渲染函数中await第三方库的初始化或资源加载options 透传Mermaid.vue会把theme暗色模式感知与代码块头属性一并传入你的渲染函数可以据此适配明暗主题缓存按 (压缩码 options) 命中修改 mermaid 内容或 options 都会触发重新渲染无需担心过期缓存渲染失败的表现自定义渲染函数抛错时错误会被 packages/client/builtin/Mermaid.vue 捕获并在幻灯片上显示为红框文本同时输出console.warn便于定位是图表语法问题还是渲染库 API 使用问题文件名与位置不能错必须是项目根目录下setup/文件夹中的mermaid-renderer.ts或 js/mts/mjs多根目录场景下每个 root 各找一个。小结setup/mermaid-renderer.ts是 Slidev 提供的一个「渲染级」扩展点通过虚拟模块发现机制自动装配利用MermaidRenderFn类型契约把 mermaid 源码与 options 交给你的第三方库并以内置 mermaid 作为安全兜底。整个功能入口代码量极少但背后串联了代码块转换lz-string 压缩、虚拟模块#slidev/setups/mermaid-renderer、组件渲染与缓存等完整链路。当你想为演示文稿的图表换上一套更有辨识度的渲染风格时按本文第一节的两个步骤即可完成接入并可以依据 packages/client/modules/mermaid.ts 的源码验证其行为是否符合预期。【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidev创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考