在 Hexo 博客里嵌入 PlantUML 图(服务端 / 客户端两套方案)

puml.online

把 PlantUML 嵌进静态博客有两条路:本地/服务端事先渲染,或者让读者浏览器现渲染。这篇是两套方案的踩坑总结。

方案 A:服务端渲染(hexo-renderer-plantuml)

工作流:<hexo> hexo generate 阶段把 ```plantuml 代码块渲染成 SVG 图片,生成的 HTML 直接包含 <svg>,不需要客户端 JS。

1
2
# 安装
npm install hexo-renderer-plantuml

配置 _config.yml

1
2
3
4
5
plantuml:
render: server # 也可以是 local(用本地 Java + plantuml.jar)
server: https://www.plantuml.com/plantuml
inline: false
syntax: plantuml

写文章:

1
2
3
4
5
6
7
8
```plantuml
@startuml
participant FE
participant API
FE -> API: POST /login
API --> FE: 200
@enduml
```

hexo generate 时插件调用 plantuml.com 拿 SVG,嵌到页面里:

1
2
3
<svg xmlns="..." viewBox="...">
<!-- 渲染好的图 -->
</svg>

优点

  • 文章 HTML 里直接是 SVG,不需要额外 JS 也能看图
  • 对 SEO 友好(搜索引擎能爬到图)
  • 部署到任何静态托管(GitHub Pages、Gitee Pages、Cloudflare Pages)都行

缺点

  • 渲染要给 plantuml.com 发请求;网络抖动的时候构建会偶发失败
  • ```plantuml 改了之后必须重新 hexo generate 才能看到效果
  • 想换渲染器升级要给 CI 加 Java 环境(如果你用 render: local

本地 Java 渲染(render: local)

不想让 plantuml.com 知道你的文档,加 Java:

1
2
apt install default-jre
# 或者用 Adoptium Temurin
1
2
3
plantuml:
render: local
plantumlJar: /usr/local/plantuml/plantuml.jar

hexo generate 阶段调 Java 生成 SVG,整个流程不依赖外网。

方案 B:客户端 WASM 渲染(TeaVM)

工作流:插件生成 <pre class="plantuml"> 块,浏览器端执行 TeaVM 编译的 plantuml.js,把代码块内容渲染成 SVG。

写文章用普通的 code block:

1
2
3
4
5
6
7
8
```plantuml
@startuml
participant FE
participant API
FE -> API: POST /login
API --> FE: 200
@enduml
```

模板里加一行:

1
2
3
4
5
6
7
8
<script src="/vendor/plantuml.js"></script>
<script>
document.querySelectorAll('pre.plantuml').forEach(p => {
const src = p.textContent;
plantuml.render(src.split('\n'), p.id, {});
p.id = '';
});
</script>

优点

  • 完全没有后端依赖,CI 只跑 hexo 本身
  • 文章改了以后刷新页面就能看到,调试循环快
  • 即使服务端挂了,博客里已发布的文章照样能渲染

缺点

  • 首次进文章需要加载 ~7MB 的 plantuml.js;移动端流量明显
  • TeaVM 编译的 WASM 对部分图(类图、状态图、用例图、组件图、对象图、部署图)存在已知 bug,会渲染失败
  • 没有 SEO 价值——爬虫不会执行 JS 拿到 SVG

方案 C:自建 PlantUML 服务器(折中)

如果文章质量比加载速度更重要,又不想依赖 plantuml.com:

1
2
FROM plantuml/plantuml-server
EXPOSE 8080
1
2
3
plantuml:
render: server
server: https://plantuml.yourcompany.internal/plantuml

内网部署一个 PlantUML server,构建时 hexo 调内部服务器渲染。Google/百度等外部爬虫也拿不到图,但内网文章全部是 SVG。

选型决策表

场景 推荐
公开博客、低频更新 方案 A(hexo-renderer-plantuml)
高频更新、内网文档、技术博客新手 方案 B(客户端 WASM)
大团队内网、要可托管、私有 方案 C(自建 PlantUML server)
完全不想配 Java/任何后端 方案 B
文章会被静态地发到 PDF/邮件/微信公众号 方案 A(提前渲染嵌入 SVG)

puml.online 当前用法

本站是 puml.online,首页(puml.online)作为博客入口,单独的 /editor/ 页面提供 WASM 编辑器。

  • 博客文章:用方案 A,通过 hexo-renderer-plantumlhexo generate 时调内网 API 渲染。
  • 编辑器:用方案 B,TeaVM 编译的 plantuml.js + viz-global.js vendor 在 source/editor/vendor/

两端隔离:博客文章不依赖任何客户端脚本,编辑器是可交互的实时引擎。这是最干净的双栈结构。

常见踩坑

  • JS Module 加载顺序vendor/plantuml.js 是 ES module,必须用 <script type="module"> 或用 <script> 加载 TeaVM 编译的 IIFE,不要混。
  • TeaVM 的 class / usecase / state 报错:当前版本 TeaVM 编译产物有 bug,已知 part-of-diagram 解析会抛 $jsException。要么换方案 A,要么把源码改写为类图变体(用 sequence + activity 表达同样意思)。
  • 服务端渲染 CN 网络问题:plantuml.com 在国内常常 502 或超时。生产环境请自建镜像,或者用方案 A + render=local 走自带的 jar。
  • 空格问题:PlantUML 服务器要求末尾严格匹配 @enduml,前置换行 / 后置空格都会触发解析。建议在编辑器里点样例代码,看渲染后再发文章。
  • 标题: 在 Hexo 博客里嵌入 PlantUML 图(服务端 / 客户端两套方案)
  • 作者: puml.online
  • 创建于 : 2026-07-29 14:25:00
  • 更新于 : 2026-08-14 21:34:29
  • 链接: https://puml.online/blog/plantuml-render-from-hexo/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。