上周将 Mermaid 从 10.6.1 升级到 11.12.1 时,踩了一系列坑。本文记录完整修复过程,希望能帮到有类似需求的同学。
+ 号的秘密Lexical error on line 1. Unrecognized text.
graph+TD++++A[index.ts]+
-----^
urlencode() 把空格编码为 +,但 JS decodeURIComponent() 不会解码 + 为空格。
// PHP
urlencode("graph TD\nA->B") // "graph+TD%0AA->B"
// JS
decodeURIComponent("graph+TD%0AA->B") // "graph+TD\nA->B" ❌ 错误!
// 修复前
const decodedCode = decodeURIComponent(mermaidCode);
// 修复后
const decodedCode = decodeURIComponent(mermaidCode.replace(/\+/g, ' '));
Cannot read properties of null (reading 'getBoundingClientRect')
刷新后正常。
mermaidDiv 变成 "幽灵元素"。
document.addEventListener('htmx:afterSwap', () => {
setTimeout(() => renderMermaid(), 50);
});
isConnectedif (!container.isConnected) {
console.warn('容器不在 DOM 中,跳过');
return;
}
container.appendChild(mermaidDiv);
if (!mermaidDiv.isConnected) {
console.warn('div 未成功添加到 DOM,跳过');
return;
}
const autoRetryContainers = new WeakSet();
async function render(container) {
const isAutoRetry = autoRetryContainers.has(container);
try {
await mermaid.run({ nodes: [mermaidDiv] });
} catch (error) {
if (!isAutoRetry) {
// 第一次失败,标记并延迟重试
autoRetryContainers.add(container);
container.innerHTML = '3秒后自动重试...';
setTimeout(() => render(container), 3000);
} else {
// 第二次失败,显示手动重试按钮
container.innerHTML = '渲染失败 <button>重试</button>';
}
}
}
const renderedContainers = new WeakSet();
const autoRetryContainers = new WeakSet();
mermaid@11.12.1,避免版本不一致导致的 API 差异。
mermaid.initialize({
startOnLoad: false,
theme: 'default'
});
| 文件 | 修改内容 |
|---|---|
public/static/js/mermaid-loader.js | HTMX 支持、DOM 检查、自动重试 |
jobs/generate_static_pages.php | URL 解码修复、自动重试 |
jobs/generate_reply_static_pages.php | URL 解码修复、自动重试 |
jobs/includes/SimpleMarkdownParser.php | 新增,供复用 |
修复耗时:3天 | 踩坑数量:5个 | 收获:Priceless
还没有人回复