From b76ccae0652d0a4f908b23f8d0a00661f6222869 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 4 Nov 2025 23:49:54 +0700 Subject: [PATCH] feat: Optimize bundling to remove shipping package.json inside mermaid's JS bundle. Move all build time injected variables to `injected.` namespace to avoid conflicts. --- .esbuild/util.ts | 9 +++++---- .vite/build.ts | 6 ++---- .../mermaid/src/diagram-api/diagram-orchestration.ts | 2 +- packages/mermaid/src/diagrams/common/common.ts | 2 +- packages/mermaid/src/diagrams/info/infoDb.ts | 3 +-- packages/mermaid/src/docs/.vitepress/config.ts | 2 +- packages/mermaid/src/mermaidAPI.ts | 5 ++--- packages/mermaid/src/rendering-util/render.ts | 2 +- packages/mermaid/src/type.d.ts | 5 ++++- vite.config.ts | 3 ++- 10 files changed, 20 insertions(+), 19 deletions(-) diff --git a/.esbuild/util.ts b/.esbuild/util.ts index 3a0ec6b41..a3e2ffe55 100644 --- a/.esbuild/util.ts +++ b/.esbuild/util.ts @@ -71,6 +71,9 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { const external: string[] = ['require', 'fs', 'path']; const outFileName = getFileName(name, options); + const { dependencies, version } = JSON.parse( + readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8') + ); const output: BuildOptions = buildOptions({ ...rest, absWorkingDir: resolve(__dirname, `../packages/${packageName}`), @@ -82,15 +85,13 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { chunkNames: `chunks/${outFileName}/[name]-[hash]`, define: { // This needs to be stringified for esbuild - includeLargeFeatures: `${includeLargeFeatures}`, + 'injected.includeLargeFeatures': `${includeLargeFeatures}`, + 'injected.version': `'${version}'`, 'import.meta.vitest': 'undefined', }, }); if (core) { - const { dependencies } = JSON.parse( - readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8') - ); // Core build is used to generate file without bundled dependencies. // This is used by downstream projects to bundle dependencies themselves. // Ignore dependencies and any dependencies of dependencies diff --git a/.vite/build.ts b/.vite/build.ts index 480dd6b30..d59f0fac3 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -78,6 +78,8 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) }, define: { 'import.meta.vitest': 'undefined', + 'injected.includeLargeFeatures': 'true', + 'injected.version': `'0.0.0'`, }, resolve: { extensions: [], @@ -94,10 +96,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) }), ...visualizerOptions(packageName, core), ], - define: { - // Needs to be string - includeLargeFeatures: 'true', - }, }; if (watch && config.build) { diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 97b9852ff..fa90e1df9 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -72,7 +72,7 @@ export const addDiagrams = () => { } ); - if (includeLargeFeatures) { + if (injected.includeLargeFeatures) { registerLazyLoadedDiagrams(flowchartElk, mindmap, architecture); } diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 045a729f7..444c9e930 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -333,7 +333,7 @@ const renderKatexUnsanitized = async (text: string, config: MermaidConfig): Prom return text.replace(katexRegex, 'MathML is unsupported in this environment.'); } - if (includeLargeFeatures) { + if (injected.includeLargeFeatures) { const { default: katex } = await import('katex'); const outputMode = config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML) diff --git a/packages/mermaid/src/diagrams/info/infoDb.ts b/packages/mermaid/src/diagrams/info/infoDb.ts index 169ceaf27..4c1a6778c 100644 --- a/packages/mermaid/src/diagrams/info/infoDb.ts +++ b/packages/mermaid/src/diagrams/info/infoDb.ts @@ -1,8 +1,7 @@ import type { InfoFields, InfoDB } from './infoTypes.js'; -import packageJson from '../../../package.json' assert { type: 'json' }; export const DEFAULT_INFO_DB: InfoFields = { - version: packageJson.version + (includeLargeFeatures ? '' : '-tiny'), + version: injected.version + (injected.includeLargeFeatures ? '' : '-tiny'), } as const; export const getVersion = (): string => DEFAULT_INFO_DB.version; diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 066fde693..55bed31da 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -1,6 +1,6 @@ import type { MarkdownOptions } from 'vitepress'; import { defineConfig } from 'vitepress'; -import packageJson from '../../../package.json' assert { type: 'json' }; +import packageJson from '../../../package.json' with { type: 'json' }; import { addCanonicalUrls } from './canonical-urls.js'; import MermaidExample from './mermaid-markdown-all.js'; diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index cf08d02f8..80deda740 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -7,7 +7,6 @@ import { select } from 'd3'; import { compile, serialize, stringify } from 'stylis'; import DOMPurify from 'dompurify'; import isEmpty from 'lodash-es/isEmpty.js'; -import packageJson from '../package.json' assert { type: 'json' }; import { addSVGa11yTitleDescription, setA11yDiagramInfo } from './accessibility.js'; import assignWithDepth from './assignWithDepth.js'; import * as configApi from './config.js'; @@ -421,12 +420,12 @@ const render = async function ( // ------------------------------------------------------------------------------- // Draw the diagram with the renderer try { - await diag.renderer.draw(text, id, packageJson.version, diag); + await diag.renderer.draw(text, id, injected.version, diag); } catch (e) { if (config.suppressErrorRendering) { removeTempElements(); } else { - errorRenderer.draw(text, id, packageJson.version); + errorRenderer.draw(text, id, injected.version); } throw e; } diff --git a/packages/mermaid/src/rendering-util/render.ts b/packages/mermaid/src/rendering-util/render.ts index aa4bceca3..c14af2391 100644 --- a/packages/mermaid/src/rendering-util/render.ts +++ b/packages/mermaid/src/rendering-util/render.ts @@ -42,7 +42,7 @@ const registerDefaultLayoutLoaders = () => { name: 'dagre', loader: async () => await import('./layout-algorithms/dagre/index.js'), }, - ...(includeLargeFeatures + ...(injected.includeLargeFeatures ? [ { name: 'cose-bilkent', diff --git a/packages/mermaid/src/type.d.ts b/packages/mermaid/src/type.d.ts index 0c88e4866..515c774b4 100644 --- a/packages/mermaid/src/type.d.ts +++ b/packages/mermaid/src/type.d.ts @@ -1,2 +1,5 @@ // eslint-disable-next-line no-var -declare var includeLargeFeatures: boolean; +declare var injected: { + version: string; + includeLargeFeatures: boolean; +}; diff --git a/vite.config.ts b/vite.config.ts index c4738458e..f86711e9a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -35,7 +35,8 @@ export default defineConfig({ }, define: { // Needs to be string - includeLargeFeatures: 'true', + 'injected.includeLargeFeatures': 'true', 'import.meta.vitest': 'undefined', + packageVersion: "'0.0.0'", }, });