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.
This commit is contained in:
Sidharth Vinod
2025-11-04 23:49:54 +07:00
parent 287a9a3fcb
commit b76ccae065
10 changed files with 20 additions and 19 deletions

View File

@@ -71,6 +71,9 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
const external: string[] = ['require', 'fs', 'path']; const external: string[] = ['require', 'fs', 'path'];
const outFileName = getFileName(name, options); const outFileName = getFileName(name, options);
const { dependencies, version } = JSON.parse(
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
);
const output: BuildOptions = buildOptions({ const output: BuildOptions = buildOptions({
...rest, ...rest,
absWorkingDir: resolve(__dirname, `../packages/${packageName}`), absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
@@ -82,15 +85,13 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
chunkNames: `chunks/${outFileName}/[name]-[hash]`, chunkNames: `chunks/${outFileName}/[name]-[hash]`,
define: { define: {
// This needs to be stringified for esbuild // This needs to be stringified for esbuild
includeLargeFeatures: `${includeLargeFeatures}`, 'injected.includeLargeFeatures': `${includeLargeFeatures}`,
'injected.version': `'${version}'`,
'import.meta.vitest': 'undefined', 'import.meta.vitest': 'undefined',
}, },
}); });
if (core) { 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. // Core build is used to generate file without bundled dependencies.
// This is used by downstream projects to bundle dependencies themselves. // This is used by downstream projects to bundle dependencies themselves.
// Ignore dependencies and any dependencies of dependencies // Ignore dependencies and any dependencies of dependencies

View File

@@ -78,6 +78,8 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
}, },
define: { define: {
'import.meta.vitest': 'undefined', 'import.meta.vitest': 'undefined',
'injected.includeLargeFeatures': 'true',
'injected.version': `'0.0.0'`,
}, },
resolve: { resolve: {
extensions: [], extensions: [],
@@ -94,10 +96,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
}), }),
...visualizerOptions(packageName, core), ...visualizerOptions(packageName, core),
], ],
define: {
// Needs to be string
includeLargeFeatures: 'true',
},
}; };
if (watch && config.build) { if (watch && config.build) {

View File

@@ -72,7 +72,7 @@ export const addDiagrams = () => {
} }
); );
if (includeLargeFeatures) { if (injected.includeLargeFeatures) {
registerLazyLoadedDiagrams(flowchartElk, mindmap, architecture); registerLazyLoadedDiagrams(flowchartElk, mindmap, architecture);
} }

View File

@@ -333,7 +333,7 @@ const renderKatexUnsanitized = async (text: string, config: MermaidConfig): Prom
return text.replace(katexRegex, 'MathML is unsupported in this environment.'); return text.replace(katexRegex, 'MathML is unsupported in this environment.');
} }
if (includeLargeFeatures) { if (injected.includeLargeFeatures) {
const { default: katex } = await import('katex'); const { default: katex } = await import('katex');
const outputMode = const outputMode =
config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML) config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML)

View File

@@ -1,8 +1,7 @@
import type { InfoFields, InfoDB } from './infoTypes.js'; import type { InfoFields, InfoDB } from './infoTypes.js';
import packageJson from '../../../package.json' assert { type: 'json' };
export const DEFAULT_INFO_DB: InfoFields = { export const DEFAULT_INFO_DB: InfoFields = {
version: packageJson.version + (includeLargeFeatures ? '' : '-tiny'), version: injected.version + (injected.includeLargeFeatures ? '' : '-tiny'),
} as const; } as const;
export const getVersion = (): string => DEFAULT_INFO_DB.version; export const getVersion = (): string => DEFAULT_INFO_DB.version;

View File

@@ -1,6 +1,6 @@
import type { MarkdownOptions } from 'vitepress'; import type { MarkdownOptions } from 'vitepress';
import { defineConfig } 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 { addCanonicalUrls } from './canonical-urls.js';
import MermaidExample from './mermaid-markdown-all.js'; import MermaidExample from './mermaid-markdown-all.js';

View File

@@ -7,7 +7,6 @@ import { select } from 'd3';
import { compile, serialize, stringify } from 'stylis'; import { compile, serialize, stringify } from 'stylis';
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import isEmpty from 'lodash-es/isEmpty.js'; import isEmpty from 'lodash-es/isEmpty.js';
import packageJson from '../package.json' assert { type: 'json' };
import { addSVGa11yTitleDescription, setA11yDiagramInfo } from './accessibility.js'; import { addSVGa11yTitleDescription, setA11yDiagramInfo } from './accessibility.js';
import assignWithDepth from './assignWithDepth.js'; import assignWithDepth from './assignWithDepth.js';
import * as configApi from './config.js'; import * as configApi from './config.js';
@@ -421,12 +420,12 @@ const render = async function (
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
// Draw the diagram with the renderer // Draw the diagram with the renderer
try { try {
await diag.renderer.draw(text, id, packageJson.version, diag); await diag.renderer.draw(text, id, injected.version, diag);
} catch (e) { } catch (e) {
if (config.suppressErrorRendering) { if (config.suppressErrorRendering) {
removeTempElements(); removeTempElements();
} else { } else {
errorRenderer.draw(text, id, packageJson.version); errorRenderer.draw(text, id, injected.version);
} }
throw e; throw e;
} }

View File

@@ -42,7 +42,7 @@ const registerDefaultLayoutLoaders = () => {
name: 'dagre', name: 'dagre',
loader: async () => await import('./layout-algorithms/dagre/index.js'), loader: async () => await import('./layout-algorithms/dagre/index.js'),
}, },
...(includeLargeFeatures ...(injected.includeLargeFeatures
? [ ? [
{ {
name: 'cose-bilkent', name: 'cose-bilkent',

View File

@@ -1,2 +1,5 @@
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
declare var includeLargeFeatures: boolean; declare var injected: {
version: string;
includeLargeFeatures: boolean;
};

View File

@@ -35,7 +35,8 @@ export default defineConfig({
}, },
define: { define: {
// Needs to be string // Needs to be string
includeLargeFeatures: 'true', 'injected.includeLargeFeatures': 'true',
'import.meta.vitest': 'undefined', 'import.meta.vitest': 'undefined',
packageVersion: "'0.0.0'",
}, },
}); });