Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/docusaurus-theme-mermaid/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

import {useState, useEffect, useMemo} from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import mermaid from 'mermaid';
import {ensureLayoutsRegistered} from './layouts';
import {loadMermaid} from './loadMermaid';

import type {RenderResult, MermaidConfig} from 'mermaid';
import type {ThemeConfig} from '@docusaurus/theme-mermaid';
Expand Down Expand Up @@ -55,7 +54,7 @@ async function renderMermaid({
text: string;
config: MermaidConfig;
}): Promise<RenderResult> {
await ensureLayoutsRegistered();
const mermaid = await loadMermaid();

/*
Mermaid API is really weird :s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
* LICENSE file in the root directory of this source tree.
*/

import mermaid from 'mermaid';
import type {Mermaid} from 'mermaid';

declare global {
// Global variable provided by bundler DefinePlugin
/* eslint-disable-next-line no-underscore-dangle */
const __DOCUSAURUS_MERMAID_LAYOUT_ELK_ENABLED__: boolean;
}

async function registerOptionalElkLayout() {
async function loadMermaidAndRegisterLayouts(): Promise<Mermaid> {
const mermaid = (await import('mermaid')).default;

// Mermaid does not support ELK layouts by default
// See https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid-layout-elk
// ELK layouts are heavy, so we made it an optional peer dependency
Expand All @@ -22,13 +24,19 @@ async function registerOptionalElkLayout() {
const elkLayout = (await import('@mermaid-js/layout-elk')).default;
mermaid.registerLayoutLoaders(elkLayout);
}

return mermaid;
}

// Ensure we only try to register layouts once
let layoutsRegistered = false;
export async function ensureLayoutsRegistered(): Promise<void> {
if (!layoutsRegistered) {
await registerOptionalElkLayout();
layoutsRegistered = true;
let MermaidPromise: Promise<Mermaid> | null = null;

// We load Mermaid with a dynamic import to code split / lazy load the library
// It is only called inside a useEffect, so loading can be deferred
// We memoize so that we don't load and register layouts multiple times
export async function loadMermaid(): Promise<Mermaid> {
if (!MermaidPromise) {
MermaidPromise = loadMermaidAndRegisterLayouts();
}
return MermaidPromise;
}
Loading