资讯动态

Mermaid config 模块:三级配置体系、深合并与安全消毒的完整 API 解析

发布时间:2026/9/7 2:16:36 来源:尧图企业网站定制
Mermaid config 模块三级配置体系、深合并与安全消毒的完整 API 解析【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaidMermaid 的所有图表渲染都依赖一套「默认配置 站点级配置 图表级指令」的三级配置体系。本文以官方 API 参考文档docs/config/setup/config/README.md为骨架完整解析config模块导出的 1 个变量与 12 个函数的签名、语义与调用关系并结合 packages/mermaid/src/config.ts 源码、深合并工具 assignWithDepth.ts 与 packages/mermaid/src/config.spec.ts 测试讲清配置从「加载」到「渲染时生效」的完整合并链路与安全消毒机制。读完你可以掌握如何正确设置站点级配置、frontmatter 指令如何参与合并、secure密钥如何保护你的应用不被注入篡改。一、config 模块导出的 API 总览官方 API 参考将config模块分为 Variables 与 Functions 两部分见 docs/config/setup/config/README.md类别导出项签名定义位置说明VariabledefaultConfigconst defaultConfig: MermaidConfigconfig.ts#L8被Object.freeze冻结的默认配置Functionevaluate(val?) booleanconfig.ts#L16把字符串/布尔值规范地转换为布尔值FunctionsetSiteConfig(conf) MermaidConfigconfig.ts#L64设置受保护的站点级siteConfigFunctionsaveConfigFromInitialize(conf) voidconfig.ts#L78保存initialize()传入的配置FunctionupdateSiteConfig(conf) MermaidConfigconfig.ts#L82在现有siteConfig上增量合并FunctiongetSiteConfig() MermaidConfigconfig.ts#L94返回当前siteConfig的深拷贝FunctionsetConfig已废弃(conf) MermaidConfigconfig.ts#L106对currentConfig做一次性覆盖更新FunctiongetConfig() MermaidConfigconfig.ts#L120返回currentConfig的深拷贝Functionsanitize(options) voidconfig.ts#L131原地删除对安全密钥与危险值的篡改尝试FunctionaddDirective(directive) voidconfig.ts#L173压入一条指令并重建渲染配置Functionreset(config siteConfig) voidconfig.ts#L194清空指令并把配置重置到站点级基线FunctiongetUserDefinedConfig() MermaidConfigconfig.ts#L227返回「initialize 配置 指令」的用户自定义部分FunctiongetEffectiveHtmlLabels(config) booleanconfig.ts#L246处理已废弃的flowchart.htmlLabels的优先级取值各函数的详细参考文档分别位于 docs/config/setup/config/variables/defaultConfig.md、docs/config/setup/config/functions/addDirective.md 等文件与上文表格一一对应。二、三级配置体系defaultConfig、siteConfig 与 currentConfig理解上面所有函数的前提是理解 packages/mermaid/src/config.ts#L19-L22 中维护的四个模块级状态let siteConfig: MermaidConfig assignWithDepth({}, defaultConfig); let configFromInitialize: MermaidConfig; let directives: MermaidConfig[] []; let currentConfig: MermaidConfig assignWithDepth({}, defaultConfig);结合 docs/config/configuration.md 的描述三级来源为defaultConfig默认配置——构建自 JSON Schema 的默认值见下节siteConfig站点级配置——由集成方通过initialize()调用设置作用于站点内的所有图表指令/Frontmatter图表级——图表作者可以在图表代码或 YAML frontmatter 中修改选定的配置参数。渲染配置render config即currentConfig是上述来源按顺序深合并后的结果图表渲染时实际读取的就是它。defaultConfig被冻结的构建期默认值defaultConfig的导出只有一行config.ts#L8export const defaultConfig: MermaidConfig Object.freeze(config);真正的默认值来自 packages/mermaid/src/defaultConfig.ts。该文件通过自定义 Vite 插件从 JSON Schema 中「只提取默认值」生成defaultConfigJson再补充无法放进 JSON 的非默认项例如sequence下的messageFont、noteFont、actorFont等是函数型默认值返回由*FontFamily/*FontSize/*FontWeight组装的字体对象class.defaultRenderer: dagre-wrapper、elk.nodePlacementStrategy: BRANDES_KOEPF等布局器默认值themeVariables默认取theme.default.getThemeVariables()。同文件还导出了configKeys——对defaultConfig递归keyify得到的合法配置键集合defaultConfig.ts#L333-L343它后面会被指令消毒器当作白名单使用。Object.freeze保证运行时任何人都无法意外修改默认配置本身所有上层配置都只能以「深拷贝 合并」的方式衍生。深合并引擎 assignWithDepth三级配置之所以能安全叠加核心是 packages/mermaid/src/assignWithDepth.ts。它扩展了Object.assign对src中每个路径为k的键递归执行Object.assign(dst[k], src[k])遇到dst[k]为undefined时自动初始化为{}再合并类型不相似时不互相覆盖若dst中该键是对象而src中是标量或反之dst原值保留避免用户只改一个叶子值却把整个子树冲掉第三参数depth默认 2控制递归深度dst/src都为对象且depth 0时退化为单层Object.assign。config模块中所有「返回配置」的函数getSiteConfig、getConfig、updateSiteConfig等都通过assignWithDepth({}, x)返回深拷贝因此调用者对返回值的修改不会污染内部状态——这一点在 config.spec.ts 的should return independent copies (not references)用例中有专门验证。三、写入侧 API如何设置站点级配置setSiteConfig一次性设定受保护基线export const setSiteConfig (conf: MermaidConfig): MermaidConfig { siteConfig assignWithDepth({}, defaultConfig); siteConfig assignWithDepth(siteConfig, conf); if (conf.theme theme[conf.theme]) { siteConfig.themeVariables theme[conf.theme].getThemeVariables(conf.themeVariables); } updateCurrentConfig(siteConfig, directives); return siteConfig; };config.ts#L64-L76注意两点conf是相对 defaultConfig 的增量而非全量替换——实现总是先深拷贝defaultConfig再合并conf当指定了已知主题时会用该主题的getThemeVariables重新计算themeVariables保证主题变量与主题名一致。setSiteConfig由mermaid.initialize(options)内部调用见 mermaidAPI.ts#L686。saveConfigFromInitialize 与 updateSiteConfigsaveConfigFromInitialize(conf)config.ts#L78-L80只做一件事把initialize传入的配置深拷贝存入configFromInitialize。它不改变任何生效配置作用有两个一是被getUserDefinedConfig读取下节二是在指令指定theme时作为themeVariables的合并基底见updateCurrentConfig中 config.ts#L39-L48 的逻辑updateSiteConfig(conf)config.ts#L82-L87则是在现有siteConfig上增量合并注意它不重新从defaultConfig起步并立即用当前指令重建currentConfig。setConfig已废弃与 getConfigAPI 参考中将setConfig标记为废弃docs/config/setup/config/functions/setConfig.md原因是Any changes to thecurrentConfigwould be overwritten by the next call toaddDirectiveorreset.从源码看确实如此setConfig调用updateCurrentConfig(currentConfig, [conf])而每次渲染前reset()都会清空directives并从siteConfig起步重建currentConfigsetConfig的修改随即丢失。因此正确用法是站点级修改走setSiteConfig/updateSiteConfig图表级修改走 frontmatter/指令。getConfig()config.ts#L120-L122返回currentConfig深拷贝其文档备注明确要求「不要反复调用应把结果存变量后传递」——因为每次调用都是一次全量深合并复制。四、读取侧 API 与 getUserDefinedConfiggetSiteConfig()config.ts#L94-L96返回siteConfig深拷贝即「站点集成者视角的基线配置」。getUserDefinedConfig()config.ts#L227-L239返回的是用户自定义部分即initialize配置与所有已压入指令的叠加不含defaultConfigexport const getUserDefinedConfig (): MermaidConfig { let userConfig: MermaidConfig {}; if (configFromInitialize) { userConfig assignWithDepth(userConfig, configFromInitialize); } for (const d of directives) { userConfig assignWithDepth(userConfig, d); } return userConfig; };config.spec.ts 的getUserDefinedConfig测试组覆盖了「空配置、仅 initialize、仅指令、二者叠加、深层嵌套覆盖、边界 undefined 值」等分支其中should retain config from initialize after reset验证了reset()清空指令后 initialize 配置仍然保留——这正是configFromInitialize独立于directives数组存储的意义。五、图表级指令addDirective 与 reset渲染时的标准调用链指令不是由用户直接调addDirective传入的而是在渲染管线中自动发生。mermaidAPI.ts#L74-L75 中configApi.reset(); configApi.addDirective(processed.config ?? {});每次渲染前先reset()回到siteConfig基线并清空指令再把该图表经 frontmatter 解析后的config作为一条指令压入。这与 docs/config/configuration.md 中「Before each rendering of a diagram, reset is called at the very beginning」的描述一致。addDirective 的附加职责addDirectiveconfig.ts#L173-L186在压入指令前做两件事调用sanitizeDirective(directive)消毒第六节详述若指令含fontFamily但未写入themeVariables.fontFamily自动补入——使顶层字体指令与主题变量体系对齐。合并与主题重算updateCurrentConfig所有写入最终都汇到私有的updateCurrentConfigconfig.ts#L24-L53合并顺序为siteConfig深拷贝 ← 依次深合并每条 directive每条先经 sanitize ← 若指令含合法 themethemeVariables theme.getThemeVariables( initialize 配置的 themeVariables ⊕ 指令的 themeVariables)其中reset(config siteConfig)config.ts#L194-L198允许显式传参重置到任意配置——mermaidAPI.ts#L732-L735 就利用这一点对外暴露了回到siteConfig与回到defaultConfig两种 reset 行为。六、安全防线sanitize 与 sanitizeDirectivesanitize拒绝篡改安全密钥与危险值sanitizeconfig.ts#L131-L166原地修改传入对象执行三类删除secure 密钥保护[secure, ...(siteConfig.secure ?? [])]中的键若出现在 options 中直接delete。源码注释特别提醒不要在日志模板字符串里打印被删的值因为恶意脚本可能利用 logger 的字符串化过程执行任意代码原型污染防护所有以__开头的键被删除XSS 防护字符串值若包含、或url(data:则整体删除注释说明拦截 data URL 是因为 base64 中可藏内联脚本的 SVG对象值递归消毒。siteConfig.secure的用法即站点集成者可把某些键声明为「安全密钥」此后任何 frontmatter/指令都无法覆盖它们。config.spec.ts 中should respect secure keys when applying directives用例验证了这一点e2e 快照 e2e/diagrams/conf-and-directives/settings-from-frontmatter-nodes-should-be-grey.mmd 则验证了 frontmatter 配置在渲染中的生效结果。sanitizeDirective指令的白名单式消毒addDirective路径上更严格一层的是 packages/mermaid/src/utils/sanitizeDirective.ts白名单键若不是configKeysdefaultConfig 的递归键集合成员、包含proto/constr、以__开头或值为null一律删除——图表作者无法通过指令注入任意键字典型配置的值模式校验对nodeColorssankey、filenameIcons/extensionIconstreeView这类「键任意、值受约束」的配置用正则校验每个值如nodeColors只允许 CSS 颜色格式可疑条目删除CSS 平衡检查themeCSS、fontFamily、altFontFamily等键的值经sanitizeCss检查花括号配对不平衡时替换为{ /* ERROR: Unbalanced CSS */ }。七、getEffectiveHtmlLabels 与 evaluate废弃选项的兼容取值getEffectiveHtmlLabelsconfig.ts#L246-L252处理flowchart.htmlLabels的弃用export const getEffectiveHtmlLabels (config: MermaidConfig): boolean { if (config.flowchart?.htmlLabels ! undefined) { issueWarning(FLOWCHART_HTML_LABELS_DEPRECATED); } return evaluate(config.htmlLabels ?? config.flowchart?.htmlLabels ?? true); };优先级为根级htmlLabels 已废弃的flowchart.htmlLabels 默认true设置了旧键即输出一次性弃用警告模块内issueWarning机制保证同一警告只打印一次。渲染管线通过 mermaidAPI.ts#L153 调用它决定 HTML 标签渲染开关。config.spec.ts 的getEffectiveHtmlLabels测试组用 8 个用例钉死了这套优先级包括「根级为 undefined 时指令级flowchart.htmlLabels: false生效」「根级true覆盖flowchart.htmlLabels: false」等组合。配套的evaluateconfig.ts#L16-L17负责把字符串型配置规范化为布尔值false、false、null、0不区分大小写、忽略首尾空白判为false其余一律true——这意味着htmlLabels: no这类非约定字符串仍会被视为开启配置时请使用规范写法。八、实践要点小结站点级配置在mermaid.initialize()传入内部经saveConfigFromInitializesetSiteConfig生效mermaidAPI.ts#L674、mermaidAPI.ts#L686运行中增量调整用updateSiteConfig图表级配置交给 frontmatter/指令即可渲染管线会自动reset()addDirective()不要试图用已废弃的setConfig做一次性覆盖——它会被下一次渲染的reset()冲掉读取配置用getConfig()取渲染配置但按文档备注缓存结果、避免重复调用需要区分「用户到底改了什么」时用getUserDefinedConfig()防御面指令白名单configKeys、secure密钥、__proto类键删除与 HTML/data-URL 拦截构成了针对 frontmatter 注入的四层消毒理解 sanitize 与 sanitizeDirective 有助于你自定义siteConfig.secure与排查「为什么我的配置没生效」类问题——多数情况下是配置键不在白名单内或被安全策略拦截可在log的 debug 级输出中确认。【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价