Decisión: Plugin Remark custom para Mermaid en Astro (vs rehype-mermaid)
Fecha: 2026-05-18
PR: #47
Estado: Adoptado
Contexto
El Workspace necesita renderizar diagramas ER y de flujo en las páginas wiki de base de datos (y futuras páginas técnicas). Los diagramas se escriben en bloques ```mermaid en el Markdown fuente.
Astro procesa el Markdown con Remark + Rehype y envía el HTML resultante a Shiki para colorear bloques de código. El reto es que Mermaid necesita ejecutar JavaScript en el cliente para transformar texto en SVG — no puede precalcularse en build time de forma segura.
Opciones evaluadas
Opción A — rehype-mermaid (descartada)
rehype-mermaid puede operar en modo pre-mermaid (preserva el texto raw en un <pre>) o en modo server-side (genera SVG en build). El modo server-side arrasta la dependencia mermaid-isomorphic, que a su vez requiere Playwright para simular un browser.
Problema crítico: Playwright no está disponible en el entorno de build de Cloudflare Pages. El build falla con error de binario no encontrado.
El modo pre-mermaid evita Playwright pero sigue añadiendo mermaid-isomorphic al árbol de dependencias (peso innecesario + riesgo de resolución rota en CI).
Opción B — Plugin Remark minimal custom (adoptada)
Plugin de ~30 LOC en astro.config.mjs que intercepta el AST Markdown antes de que llegue a Shiki:
function remarkMermaidPreserve() {
return (tree) => {
const visit = (node) => {
if (Array.isArray(node.children)) {
node.children = node.children.map((child) => {
if (child.type === 'code' && child.lang === 'mermaid') {
return {
type: 'html',
value: `<pre class="mermaid">${escapeHtml(child.value || '')}</pre>`,
};
}
visit(child);
return child;
});
}
};
visit(tree);
};
}
El HTML generado contiene <pre class="mermaid"> con el código raw. En el cliente, mermaid.js (cargado bajo demanda solo si la página tiene al menos un pre.mermaid) transforma cada bloque en SVG interactivo.
Decisión
Adoptar Opción B (plugin Remark custom).
Consecuencias
Positivas
- Zero dependencias nuevas de build:
mermaidse añade apackage.jsonsolo para bundling client-side; no hay Playwright nimermaid-isomorphic. - CF Pages build verde: sin binarios de sistema requeridos.
- Carga lazy:
mermaid.js(~2.5 MB minificado) solo se importa dinámicamente si la página tiene diagramas. Páginas sin diagramas no pagan el coste. - Theme dark: configurado en la inicialización client-side, coherente con el tema del Workspace.
- Mantenibilidad: el plugin es autocontenido en
astro.config.mjs, fácil de auditar.
Negativas / limitaciones
- Los diagramas requieren JavaScript en el cliente para renderizarse (no hay SVG estático en el HTML servido).
- Sin JS, el usuario ve el código fuente Mermaid en texto plano — aceptable dado que el Workspace siempre requiere JS.
- No hay pre-rendering de SVG para OG/social cards (no es un requisito actual).
Archivos modificados
| Archivo | Cambio |
|---|---|
astro.config.mjs | Plugin remarkMermaidPreserve + escapeHtml + remarkPlugins: [remarkMermaidPreserve] |
package.json | "mermaid": "^11.15.0" añadido a dependencies |
pnpm-lock.yaml | Lockfile actualizado |
Véase también
- [[workspace-tech—bd—tecnico]]
- [[workspace-tech—bd—coloquial]]
- [[crearack-tech—bd—tecnico]]
- [[workspace—que-es-workspace]]