0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor: fix mermaid in production (#6149)

Use dynamic CDN import to use Mermaid as Parcel has issues on handling the
static import in production.
This commit is contained in:
Gao Sun 2024-07-01 18:06:38 +08:00 committed by GitHub
parent 88dd7d2f87
commit dd69c1c4f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 20 deletions

View file

@ -1,15 +1,19 @@
import { Theme } from '@logto/schemas';
import mermaid from 'mermaid';
import { type Mermaid as MermaidType } from 'mermaid';
import { useEffect } from 'react';
import useTheme from '@/hooks/use-theme';
mermaid.initialize({
startOnLoad: true,
theme: 'default',
securityLevel: 'loose',
fontFamily: 'Fira Code',
});
const loadMermaid = async () => {
// Define this variable to "outsmart" the detection of the dynamic import by Parcel:
// https://github.com/parcel-bundler/parcel/issues/7064#issuecomment-942441649
const uri = 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const imported: { default: MermaidType } = await import(uri);
return imported.default;
};
const mermaidPromise = loadMermaid();
type Props = {
readonly children: string;
@ -24,14 +28,16 @@ export default function Mermaid({ children }: Props) {
const theme = useTheme();
useEffect(() => {
mermaid.initialize({
theme: themeToMermaidTheme[theme],
});
(async () => {
const mermaid = await mermaidPromise;
mermaid.initialize({
startOnLoad: false,
theme: themeToMermaidTheme[theme],
securityLevel: 'loose',
});
await mermaid.run();
})();
}, [theme]);
useEffect(() => {
mermaid.contentLoaded();
}, []);
return <div className="mermaid">{children}</div>;
}

View file

@ -41,13 +41,16 @@ export default function koaSecurityHeaders<StateT, ContextT, ResponseBodyT>(
/** Google Sign-In (GSI) origin for Google One Tap. */
const gsiOrigin = 'https://accounts.google.com/gsi/';
// We use react-monaco-editor for code editing in the admin console. It loads the monaco editor asynchronously from a CDN.
// We have the following use cases:
//
// 1. We use `react-monaco-editor` for code editing in the admin console. It loads the monaco
// editor asynchronously from jsDelivr.
// 2. We use `mermaid` for rendering diagrams in the admin console. It loads the mermaid library
// asynchronously from jsDelivr since Parcel has issues with loading it directly in production.
//
// Allow the CDN src in the CSP.
// Allow blob: for monaco editor to load worker scripts
const monacoEditorCDNSource = [
'https://cdn.jsdelivr.net/npm/monaco-editor@0.43.0/min/vs/',
'blob:',
];
const cdnSources = ['https://cdn.jsdelivr.net/', 'blob:'];
/**
* Default Applied rules:
@ -122,7 +125,7 @@ export default function koaSecurityHeaders<StateT, ContextT, ResponseBodyT>(
scriptSrc: [
"'self'",
...conditionalArray(!isProduction && ["'unsafe-eval'", "'unsafe-inline'"]),
...monacoEditorCDNSource,
...cdnSources,
],
connectSrc: ["'self'", logtoOrigin, ...adminOrigins, ...coreOrigins, ...developmentOrigins],
// Allow Main Flow origin loaded in preview iframe