新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/9/29 2:30:37来源:尧图网络
零依赖离线Mermaid本地编辑器:构建管线与渲染沙箱拆解
零依赖离线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),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Gentle-AI 的 RDD(Receipt-Driven Development)修复实录:从失控的 Agent 到可复现的摩擦基准 2026/9/29 3:25:32

Gentle-AI 的 RDD(Receipt-Driven Development)修复实录:从失控的 Agent 到可复现的摩擦基准

【免费下载链接】gentle-ai Gentle-AI configures the AI coding agents you already use: Claude Code, Cursor, OpenCode, Codex, Pi, and more. Choose persistent memory, Organic-Driven Development, curated skills, MCP servers, personas, and optional bounded revie…

阅读更多 →
从零开始AI工程:构建数据-模型-服务闭环的实战指南 2026/9/29 3:25:32

从零开始AI工程:构建数据-模型-服务闭环的实战指南

1. 为什么“从零开始学AI工程”是一条更难、但也更扎实的路先交代一下背景。我最早接触“ai-engineering”这个词的时候,和大多数人一样,第一反应是:这不就是调库、调参、跑模型吗?结果真正动手做项目之后才发现,AI工程…

阅读更多 →
深度学习物理层实战:从CSI估计到DQN位置验证的综述 2026/9/29 3:25:32

深度学习物理层实战:从CSI估计到DQN位置验证的综述

简介:这份PDF文献面向通信工程、信号处理方向的研究生与科研人员,聚焦深度学习在物理层信号处理中的落地路径,帮助读者理解5G高可靠、低时延场景下传统通信理论面临的复杂性与计算挑战。全文围绕信道状态信息(CSI)估计…

阅读更多 →
用 Claude Code 一个周末复活 30 年前传奇游戏:Go+React+MongoDB 全栈实战 2026/9/29 3:25:32

用 Claude Code 一个周末复活 30 年前传奇游戏:Go+React+MongoDB 全栈实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
AI工程从零到上线:环境配置、数据处理与模型部署实践指南 2026/9/29 3:25:32

AI工程从零到上线:环境配置、数据处理与模型部署实践指南

1. AI工程到底是什么,先别急着写代码先说个很现实的事情:很多人一听“ai-engineering”,第一反应是“我要去学深度学习、调参、训练大模型”,结果花了两周看神经网络数学推导,最后连一个能用的服务都没跑起来。这个方向…

阅读更多 →
得物交易搜索:从向量检索到生成式召回的范式转移与工程实践 2026/9/29 3:25:25

得物交易搜索:从向量检索到生成式召回的范式转移与工程实践

1. 从“卷向量”到“生成式召回”的范式转移逻辑1.1 为什么传统向量检索在交易搜索场景里越来越吃力做电商搜索的人都有一个共同感受:向量检索这条路,过去几年确实吃到了红利,但最近两年越来越“卷”不动了。得物交易搜索这种场景&#xff0c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉