资讯动态

零依赖离线Mermaid本地编辑器:构建管线与渲染沙箱拆解

发布时间:2026/9/29 2:30:32 来源:尧图企业网站定制
零依赖离线Mermaid本地编辑器构建管线与渲染沙箱拆解【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid一个完整的所见即所得图编辑器零后端、零 CDN、运行时只加载两个本地脚本它就藏在 Mermaid 官方仓库的private子包里。它就是 packages/mermaid-local-editor——一个从dist/产物直接离线运行的 Mermaid 本地编辑器。一键构建命令pnpm build:mermaid:full在仓库根目录只需执行一条命令即可完成构建并拉起本地静态服务pnpm build:mermaid:full执行后浏览器打开 http://localhost:8081你会看到左侧是 Mermaid 源码文本域、右侧是流程图预览区的双栏布局顶部工具栏提供多图切换、视图重置与 SVG 导出断网状态下继续输入、缩放、切换图表均不受影响。数据流鸟瞰从一次键入到可恢复的视图状态你在左侧文本域敲下的字符会依次经过四个处理节点每个节点只接收上一节点的产物渲染mermaid.render()把源码编译成 SVG 字符串此刻内容还是未净化的净化DOMPurify按白名单剥离危险标签与属性仅放行 Mermaid 渲染必需的foreignObject标签和xmlns属性沙箱展示净化后的 SVG 写入新建的sandbox iframe成为预览区唯一的内容来源持久化源码与缩放平移得到的{ scale, panX, panY }视图状态一起写入localStorage下次启动时直接恢复到上次的视角。因为流程是单向的模块之间几乎没有直接耦合唯一的交汇点是state这个视图状态对象。源码布局与这条流水线一一对应static/ ├── index.html # 工具栏与双栏骨架 ├── app.js # 装配入口持有 render/load/applyTransform 主流程 ├── styles.css └── js/ ├── config.js # mermaid.initialize 与全局视图状态 ├── renderer.js # 渲染 → 净化 → 沙箱 ├── storage.js # localStorage 多图管理 ├── ui.js # 工具栏事件与防抖自动保存 └── navigation.js # 键盘节点导航核心机制深挖为什么用拷贝式构建链而非把编辑器打进主包如果把编辑器当作主包的一部分参与 bundle它会拖着全部图类型的解析器一起膨胀且编辑器改一行代码就要触发 Mermaid 运行时的完整重构建。构建脚本因此把编辑器当纯静态站处理只取已构建好的mermaid.min.js和依赖目录里的purify.min.js用cpy平铺进vendor/子目录。根 package.json 中该命令的真实定义是一条五段链每一段只做一件事pnpm clean pnpm build:mermaid pnpm copy:editor \ pnpm copy:mermaid pnpm copy:dompurify pnpm serve:distcopy:editor用**/*原样复制static/下所有文件保证index.html里的./vendor/...、./app.js相对引用在产物目录中结构不变copy:dompurify则直接从 pnpm 扁平化存储的dompurify*/版本化目录里取purify.min.js--flat让产物永远是干净的vendor/两个文件。代价是编辑器持有的是 Mermaid 运行时的构建时快照dist/根目录与vendor/下的两份mermaid.min.js没有自动同步机制升级 Mermaid 必须重跑整条链。sandbox iframe 如何保证用户输入碰不到主页面若渲染出的 SVG 直接插进主页面 DOM任何残余的事件处理器或脚本载荷都会与工具栏、存储代码共享同一 origin 和权限一条onload就足以读走localStorage里的全部图表。所以 renderer.js 的常规分支坚持永不直接插入主页面const iframe document.createElement(iframe); // 只给同源权限、不放开 allow-scripts预览与主页面形成硬边界 iframe.sandbox allow-same-origin; preview.appendChild(iframe); state.iframeRef iframe; // 主页面只负责传数据节点本身交给 iframe 文档避免跨文档直接操作 const svgEl new DOMParser() .parseFromString(cleanSvg, image/svgxml) .documentElement; svgEl.setAttribute(xmlns, http://www.w3.org/2000/svg); iframe.contentDocument.body.appendChild( iframe.contentDocument.importNode(svgEl, true) );代价是隔离带来的操作成本applyTransform()的缩放平移只能经state.iframeRef.contentDocument跨文档取到svg元素每处访问都要判空E2E 分支IS_E2E为真时净化后直插 DOM正是为绕过这一成本、让自动化截图可直接断言而存在的。视图状态如何保证缩放位置刷新后不变若缩放平移只改 CSS用户排好的视角会在切换图表或刷新后丢失多图工具的使用成本会高到不可接受。所以编辑器把视图状态当作与源码同级的一等数据逐帧写回存储function applyTransform() { const svg state.iframeRef.contentDocument?.querySelector(svg); // 钳制平移上限防止极端拖拽下 transform 数值漂移到无穷 state.panX Math.max(-20000, Math.min(20000, state.panX)); svg.style.transform translate(${state.panX}px, ${state.panY}px) scale(${state.scale}); // 视图随图表一起落盘切换图表与刷新后才能恢复上次视角 storage.updateCurrent({ view: { scale: state.scale, panX: state.panX, panY: state.panY }, }); }因为localStorage里单张图的结构是{ [名称]: { src, view } }见 storage.js源码 视角成对存取300ms 防抖自动保存ui.js也写同一结构忘记点 Save 也不会丢源码。代价是applyTransform在每次滚轮与拖拽事件里都触发一次localStorage写入高频滚动时序列化开销随图表数量线性放大。防御与容错用户输入要过的四道闸威胁/故障向量防御层对应代码位置失效后果图源码中的点击跳转与链接注入securityLevel: strict解析层抑制config.js的initMermaid点击节点触发外部跳转SVG 中注入script、危险属性DOMPurify 白名单净化豁免foreignObject/xmlnsrenderer.js的renderDiagram危险内容进入 DOM残余on*内联事件二次遍历删除所有on前缀属性renderer.js的renderDiagram节点插入时触发onload等事件残余载荷在预览区执行sandboxallow-same-origin无allow-scriptsrenderer.js的 iframe 创建预览逃逸沙箱、触碰主页面与存储Mermaid 语法错误try/catch后以红色pre展示e.messagerenderer.js的catch分支白屏用户无法定位错误极端拖拽导致视图状态溢出panX/panY钳制在±20000app.js的applyTransformtransform 漂移、画布不可寻这是解析、净化、属性、沙箱四层纵深防御的堆叠任何单层被绕过都不会走到脚本执行表格下半部分属于容错层只保证出错仍可用不承担安全职责。动手改造清单如果你要换默认主题或首次访问内容入口是static/js/config.js的theme字段与static/js/storage.js中默认main图的src影响范围是编辑器内两个文件、不触碰构建脚本注意构建链是原样拷贝static/改完必须重跑pnpm build:mermaid:full才能反映到dist/产物。如果你要调缩放范围或平移手感滚轮系数-0.0015与0.2/4的缩放钳制写死在renderer.js的doc.onwheel分支±20000平移钳制在app.js影响范围是这两个文件由于只改静态源、不动运行时构建重跑一次拷贝步骤即可验证。收束离线能力不等于没有依赖而是两段闭环构建期把vendor/收拢运行期把沙箱收拢。构建期收拢 运行期隔离这套模式可以直接移植到你自己的私有化部署工具里。【免费下载链接】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 小时内与您沟通定制方案

免费获取报价 →
↑