首页
/ mermaid updateSiteConfig() 站点级配置 API:合并语义、实现细节与 setSiteConfig 的对比

mermaid updateSiteConfig() 站点级配置 API:合并语义、实现细节与 setSiteConfig 的对比

2026-09-06 14:29:45作者:俞予舒Fleming

本篇聚焦 mermaid 配置体系中的 updateSiteConfig() API:它负责在不重置 siteConfig 的前提下,把新的配置增量深合并(deep merge)进站点级配置,并同步刷新当前生效配置。读完本文,你将理解它在 defaultConfig → siteConfig → directives → currentConfig 配置层级中的位置、它与 setSiteConfig() 的关键区别、深合并的底层实现(assignWithDepth),以及它在 run() 渲染主流程中的实际调用场景,能够正确地在应用初始化或动态调参时使用这一 API。

函数签名与来源

根据 API 参考文档 updateSiteConfig.md,该函数的签名为:

updateSiteConfig(conf: MermaidConfig): MermaidConfig
  • 参数conf,类型为 MermaidConfig,即本次要合并进 siteConfig 的配置对象。
  • 返回值MermaidConfig,即合并完成后的最新 siteConfig
  • 定义位置packages/mermaid/src/config.ts(第 82 行)。

该文档为自动生成的 API 参考(文首注明 "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT"),因此本文结合源码对其行为做完整展开。

配置层级:defaultConfig、siteConfig 与 currentConfig

要理解 updateSiteConfig(),先看 config.ts 顶部的模块级状态:

export const defaultConfig: MermaidConfig = Object.freeze(config); // 全局默认配置,被冻结

let siteConfig: MermaidConfig = assignWithDepth({}, defaultConfig);
let configFromInitialize: MermaidConfig;
let directives: MermaidConfig[] = [];
let currentConfig: MermaidConfig = assignWithDepth({}, defaultConfig);

mermaid 维护着一套分层配置:

层级 变量 生命周期 说明
默认配置 defaultConfig 永久 冻结(Object.freeze)的出厂默认值,不可变
站点配置 siteConfig 跨渲染持久 面向"整站/整应用"的配置基线,reset() 会把 currentConfig 还原到它
指令配置 directives 每次 parse/render 解析出的 YAML frontmatter 图表内声明的覆盖项
当前配置 currentConfig 每次更新重算 siteConfigdirectives 合并、并应用主题变量后的最终生效值

siteConfig 的定位在同目录的 setSiteConfig 文档 中有明确说明:"The siteConfig is a protected configuration for repeat use. Calls to reset() will reset the currentConfig to siteConfig." 也就是说,siteConfig 是"受保护的、可重复使用"的配置基线——updateSiteConfig() 正是用来维护这个基线的增量更新入口。

实现走读:深合并 + 重算 currentConfig

updateSiteConfig() 的完整实现非常精炼(config.ts 第 82–87 行):

export const updateSiteConfig = (conf: MermaidConfig): MermaidConfig => {
  siteConfig = assignWithDepth(siteConfig, conf);
  updateCurrentConfig(siteConfig, directives);

  return siteConfig;
};

三步拆解:

  1. assignWithDepth(siteConfig, conf):把入参 conf 深合并进现有的 siteConfig(而非整体替换)。这是它与 setSiteConfig() 最本质的区别。
  2. updateCurrentConfig(siteConfig, directives):以新的 siteConfig 为底,叠加当前积累的 directives,重算 currentConfig。从 updateCurrentConfig 的实现 看,它会依次:深拷贝 siteConfig → 逐个 sanitize 后合并所有 directives → 若涉及 theme 字段,则通过 theme[cfg.theme].getThemeVariables(...) 把主题变量(themeVariables)解析成具体值 → 写入 currentConfig 并执行 checkConfig 校验。
  3. 返回新的 siteConfig,调用方可直接拿到合并结果。

与之对比,setSiteConfig 的实现是:

export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => {
  siteConfig = assignWithDepth({}, defaultConfig); // 从 defaultConfig 全新起步
  siteConfig = assignWithDepth(siteConfig, conf); // 再合入 conf
  ...
};

两者对比清晰:

  • setSiteConfig(conf)defaultConfig + conf丢弃此前 siteConfig 中已有的其他增量,属于"整体重建";
  • updateSiteConfig(conf)现有 siteConfig + conf保留原有增量,只叠加/覆盖 conf 中出现的键,属于"增量更新"。

深合并语义:assignWithDepth 如何工作

assignWithDepth 定义在 packages/mermaid/src/assignWithDepth.ts,是对 Object.assign 的扩展,支持任意深度对象合并,并有两条对配置合并很关键的行为:

  • undefined 目标键自动初始化:若目标对象缺少某键,会自动初始化为 {}(或 [])后再递归合并,而不是直接抛错或跳过。
  • 异构类型不相互覆盖(non-clobber):当 dst 中某键是对象、而 src 中同键是字符串/数字等原始值时,保留 dst 的原值。文件头部的 JSDoc 给出了官方示例:
const config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
const config_1 = { foo: 'foo', bar: 'bar' };
const result = assignWithDepth(config_0, config_1);
//-> result: { foo: { bar: 'bar' }, bar: 'bar' }
// 若用传统 Object.assign,config_0 的 foo 会被 config_1 的 'foo' 覆盖

updateSiteConfig() 的实际含义:传入 { theme: 'dark' } 只会覆盖主题名,themeVariablesflowchart 等既有嵌套配置原样保留;但传入一个与既有对象键同名的原始值不会把那个对象打平,这是与 Object.assign 语义的重要差异,调参时需要留意。

主流程调用点:run() 中的 startOnLoad 同步

updateSiteConfig() 并不只是留给外部手动调用的 API,mermaid 自身渲染主流程就会使用它。在 packages/mermaid/src/mermaid.tsrunThrowsErrorsrun() 的内部实现)中:

if (conf?.startOnLoad !== undefined) {
  log.debug('Start On Load: ' + conf?.startOnLoad);
  mermaidAPI.updateSiteConfig({ startOnLoad: conf?.startOnLoad });
}

即在每次 run() 处理页面上的 .mermaid 节点前,若当前配置里显式声明了 startOnLoad,就通过 updateSiteConfig 把它持久化进 siteConfig,使该选项在后续的 reset() 往返中不会丢失。这体现了 updateSiteConfig 的"增量持久化"定位:只把关心的少数键同步进站点基线,而不触碰其余配置。

API 暴露方式

该函数通过内部冻结对象 mermaidAPI 暴露(packages/mermaid/src/mermaidAPI.ts):

export const mermaidAPI = Object.freeze({
  render,
  parse,
  initialize,
  getConfig: configApi.getConfig,
  getSiteConfig: configApi.getSiteConfig,
  updateSiteConfig: configApi.updateSiteConfig,
  reset: () => { configApi.reset(); },
  globalReset: () => { configApi.reset(configApi.defaultConfig); },
  defaultConfig: configApi.defaultConfig,
});

配合 getSiteConfigconfig.ts 第 94–96 行,返回 siteConfig 的深拷贝)和 reset(),一个典型的使用模式是:

import mermaid from 'mermaid';

// 1) 以增量方式更新站点级配置(保留既有 siteConfig 中其他增量)
mermaid.mermaidAPI.updateSiteConfig({ startOnLoad: true, theme: 'dark' });

// 2) 查看更新后的 siteConfig 基线
const site = mermaid.mermaidAPI.getSiteConfig();

// 3) 需要时重置 currentConfig 回到 siteConfig 基线
mermaid.mermaidAPI.reset();

测试用例对合并语义的验证

单元测试直接验证了 updateSiteConfig 的"保留既有键、追加新键"行为。在 packages/mermaid/src/mermaidAPI.spec.ts 的 "copies an object into the configuration" 用例中:

const object = { test1: 1, test2: false };
mermaidAPI.initialize({ testObject: object });

// 增量更新:只传入新键 test3
mermaidAPI.updateSiteConfig({ testObject: { test3: true } });
const config = mermaidAPI.getConfig();

expect(config.testObject.test1).toBe(1);      // 既有键保留
expect(config.testObject.test2).toBe(false);   // 既有键保留
expect(config.testObject.test3).toBe(true);    // 新键被合并进来

这组断言与 assignWithDepth 的深合并语义一一对应:updateSiteConfig 只覆盖入参中显式出现的键,testObject 下未提及的 test1test2 均原样保留。同一测试文件中(第 653–664 行)的 "resets mermaid config to global defaults" 用例则验证了 initialize + setConfig + reset 的往返语义,可结合理解 siteConfig 作为重置基线的角色。

小结与注意事项

  • updateSiteConfig(conf)增量深合并 siteConfig 并立即重算 currentConfig 的 API,返回合并后的 siteConfigsetSiteConfig 则是基于 defaultConfig整体重建。需要保留既有站点增量时用前者。
  • 合并由 assignWithDepth 驱动,注意其"异构类型不覆盖"的特殊语义,避免误以为原始值能覆盖对象。
  • siteConfigreset() 的还原目标(见 reset 文档),因此通过 updateSiteConfig 写入的配置在 reset() 后依然保留,属于"应用级持久"配置;而 directives(图表内 frontmatter)属于单次解析的临时覆盖。
  • 该 API 在 run() 主流程中被用于持久化 startOnLoadmermaid.ts),印证了它"小范围增量同步"的设计定位。
  • 本文所述行为均基于当前仓库源码验证,适用前提是仓库当前版本的 packages/mermaid 包实现。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388