Merge pull request #4734 from mermaid-js/sidv/tinyMermaid

Add `mermaid.tiny.min.js`. 69.7% size reduction.
This commit is contained in:
Sidharth Vinod
2025-05-09 05:27:29 +00:00
committed by GitHub
16 changed files with 171 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
import { build } from 'esbuild';
import { mkdir, writeFile } from 'node:fs/promises';
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
import { packageOptions } from '../.build/common.js';
import { generateLangium } from '../.build/generateLangium.js';
import type { MermaidBuildOptions } from './util.js';
@@ -31,7 +31,15 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
// mermaid.js
{ ...iifeOptions },
// mermaid.min.js
{ ...iifeOptions, minify: true, metafile: shouldVisualize }
{ ...iifeOptions, minify: true, metafile: shouldVisualize },
// mermaid.tiny.min.js
{
...iifeOptions,
minify: true,
includeLargeFeatures: false,
metafile: shouldVisualize,
sourcemap: false,
}
);
}
if (entryName === 'mermaid-zenuml') {
@@ -70,6 +78,20 @@ const handler = (e) => {
process.exit(1);
};
const buildTinyMermaid = async () => {
await mkdir('./packages/tiny/dist', { recursive: true });
await rename(
'./packages/mermaid/dist/mermaid.tiny.min.js',
'./packages/tiny/dist/mermaid.tiny.js'
);
// Copy version from mermaid's package.json to tiny's package.json
const mermaidPkg = JSON.parse(await readFile('./packages/mermaid/package.json', 'utf8'));
const tinyPkg = JSON.parse(await readFile('./packages/tiny/package.json', 'utf8'));
tinyPkg.version = mermaidPkg.version;
await writeFile('./packages/tiny/package.json', JSON.stringify(tinyPkg, null, 2) + '\n');
};
const main = async () => {
await generateLangium();
await mkdir('stats', { recursive: true });
@@ -78,6 +100,7 @@ const main = async () => {
for (const pkg of packageNames) {
await buildPackage(pkg).catch(handler);
}
await buildTinyMermaid();
};
void main();

View File

@@ -14,6 +14,7 @@ export interface MermaidBuildOptions extends BuildOptions {
metafile: boolean;
format: 'esm' | 'iife';
options: PackageOptions;
includeLargeFeatures: boolean;
}
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'> = {
@@ -21,6 +22,7 @@ export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'>
metafile: false,
core: false,
format: 'esm',
includeLargeFeatures: true,
} as const;
const buildOptions = (override: BuildOptions): BuildOptions => {
@@ -39,12 +41,18 @@ const buildOptions = (override: BuildOptions): BuildOptions => {
};
};
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
const getFileName = (
fileName: string,
{ core, format, minify, includeLargeFeatures }: MermaidBuildOptions
) => {
if (core) {
fileName += '.core';
} else if (format === 'esm') {
fileName += '.esm';
}
if (!includeLargeFeatures) {
fileName += '.tiny';
}
if (minify) {
fileName += '.min';
}
@@ -54,25 +62,27 @@ const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOpt
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
const {
core,
metafile,
format,
minify,
options: { name, file, packageName },
globalName = 'mermaid',
includeLargeFeatures,
...rest
} = options;
const external: string[] = ['require', 'fs', 'path'];
const outFileName = getFileName(name, options);
const output: BuildOptions = buildOptions({
...rest,
absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
entryPoints: {
[outFileName]: `src/${file}`,
},
metafile,
minify,
globalName,
logLevel: 'info',
chunkNames: `chunks/${outFileName}/[name]-[hash]`,
define: {
// This needs to be stringified for esbuild
includeLargeFeatures: `${includeLargeFeatures}`,
'import.meta.vitest': 'undefined',
},
});

View File

@@ -94,6 +94,10 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
}),
...visualizerOptions(packageName, core),
],
define: {
// Needs to be string
includeLargeFeatures: 'true',
},
};
if (watch && config.build) {

View File

@@ -98,6 +98,12 @@ Mermaid can load multiple diagrams, in the same page.
> Try it out, save this code as HTML and load it using any browser.
> (Except Internet Explorer, please don't use Internet Explorer.)
## Tiny Mermaid
We offer a smaller version of Mermaid that's approximately half the size of the full library. This tiny version doesn't support Mindmap Diagrams, Architecture Diagrams, KaTeX rendering, or lazy loading.
If you need a more lightweight version without these features, you can use [Mermaid Tiny](https://github.com/mermaid-js/mermaid/tree/develop/packages/tiny).
## Enabling Click Event and Tags in Nodes
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduced in version 8.2 as a security improvement, aimed at preventing malicious use.

View File

@@ -354,6 +354,7 @@ To Deploy Mermaid:
- [Mermaid Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
- [Mermaid CLI](https://github.com/mermaid-js/mermaid-cli)
- [Mermaid Tiny](https://github.com/mermaid-js/mermaid/tree/develop/packages/tiny)
- [Mermaid Webpack Demo](https://github.com/mermaidjs/mermaid-webpack-demo)
- [Mermaid Parcel Demo](https://github.com/mermaidjs/mermaid-parcel-demo)

View File

@@ -27,6 +27,7 @@ import block from '../diagrams/block/blockDetector.js';
import architecture from '../diagrams/architecture/architectureDetector.js';
import { registerLazyLoadedDiagrams } from './detectType.js';
import { registerDiagram } from './diagramAPI.js';
import '../type.d.ts';
let hasLoadedDiagrams = false;
export const addDiagrams = () => {
@@ -69,6 +70,11 @@ export const addDiagrams = () => {
return text.toLowerCase().trimStart().startsWith('---');
}
);
if (includeLargeFeatures) {
registerLazyLoadedDiagrams(flowchartElk, mindmap, architecture);
}
// Ordering of detectors is important. The first one to return true will be used.
registerLazyLoadedDiagrams(
c4,
@@ -81,10 +87,8 @@ export const addDiagrams = () => {
pie,
requirement,
sequence,
flowchartElk,
flowchartV2,
flowchart,
mindmap,
timeline,
git,
stateV2,
@@ -95,7 +99,6 @@ export const addDiagrams = () => {
packet,
xychart,
block,
architecture,
radar
);
};

View File

@@ -341,6 +341,7 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
return text.replace(katexRegex, 'MathML is unsupported in this environment.');
}
if (includeLargeFeatures) {
const { default: katex } = await import('katex');
const outputMode =
config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML)
@@ -364,6 +365,12 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
.replace(/\n/g, ' ')
.replace(/<annotation.*<\/annotation>/g, '')
);
}
return text.replace(
katexRegex,
'Katex is not supported in @mermaid-js/tiny. Please use the full mermaid library.'
);
};
export default {

View File

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

View File

@@ -92,6 +92,12 @@ Mermaid can load multiple diagrams, in the same page.
> Try it out, save this code as HTML and load it using any browser.
> (Except Internet Explorer, please don't use Internet Explorer.)
## Tiny Mermaid
We offer a smaller version of Mermaid that's approximately half the size of the full library. This tiny version doesn't support Mindmap Diagrams, Architecture Diagrams, KaTeX rendering, or lazy loading.
If you need a more lightweight version without these features, you can use [Mermaid Tiny](https://github.com/mermaid-js/mermaid/tree/develop/packages/tiny).
## Enabling Click Event and Tags in Nodes
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduced in version 8.2 as a security improvement, aimed at preventing malicious use.

View File

@@ -109,6 +109,7 @@ To Deploy Mermaid:
- [Mermaid Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
- [Mermaid CLI](https://github.com/mermaid-js/mermaid-cli)
- [Mermaid Tiny](https://github.com/mermaid-js/mermaid/tree/develop/packages/tiny)
- [Mermaid Webpack Demo](https://github.com/mermaidjs/mermaid-webpack-demo)
- [Mermaid Parcel Demo](https://github.com/mermaidjs/mermaid-parcel-demo)

View File

@@ -5,7 +5,6 @@
// @ts-ignore TODO: Investigate D3 issue
import { select } from 'd3';
import { compile, serialize, stringify } from 'stylis';
// @ts-ignore: TODO Fix ts errors
import DOMPurify from 'dompurify';
import isEmpty from 'lodash-es/isEmpty.js';
import packageJson from '../package.json' assert { type: 'json' };

2
packages/mermaid/src/type.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
// eslint-disable-next-line no-var
declare var includeLargeFeatures: boolean;

43
packages/tiny/README.md Normal file
View File

@@ -0,0 +1,43 @@
# Tiny Mermaid
This is a tiny version of mermaid that is optimized for the web. It is a subset of the mermaid library and is designed to be used in the browser via CDN.
## Lazy loading
The original mermaid library supports lazy loading, so it will be faster on the initial load, and only load the required diagrams.
This is not supported in the tiny mermaid library. So it's always recommended to use the full mermaid library unless you have a very specific reason to reduce the bundle size.
## Removals from mermaid
This does not support
- Mindmap Diagram
- Architecture Diagram
- Katex rendering
- Lazy loading
## Usage via NPM
This package is not meant to be installed directly from npm. It is designed to be used via CDN.
If you need to use mermaid in your project, please install the full [`mermaid` package](https://www.npmjs.com/package/mermaid) instead.
## Usage via CDN
### Latest version
```html
<script src="https://cdn.jsdelivr.net/npm/@mermaid-js/tiny/dist/mermaid.tiny.js"></script>
```
### Specific version
```html
<!-- Format -->
<script src="https://cdn.jsdelivr.net/npm/@mermaid-js/tiny@<MERMAID_MAJOR_VERSION>/dist/mermaid.tiny.js"></script>
<!-- Pinning major version -->
<script src="https://cdn.jsdelivr.net/npm/@mermaid-js/tiny@11/dist/mermaid.tiny.js"></script>
<!-- Pinning specific version -->
<script src="https://cdn.jsdelivr.net/npm/@mermaid-js/tiny@11.6.0/dist/mermaid.tiny.js"></script>
```

View File

@@ -0,0 +1,25 @@
{
"name": "@mermaid-js/tiny",
"version": "11.6.0",
"description": "Tiny version of mermaid",
"type": "commonjs",
"main": "./dist/mermaid.tiny.js",
"scripts": {
"clean": "rimraf dist"
},
"repository": {
"type": "git",
"url": "https://github.com/mermaid-js/mermaid"
},
"author": "Sidharth Vinod",
"license": "MIT",
"dependencies": {},
"devDependencies": {},
"files": [
"dist/",
"README.md"
],
"publishConfig": {
"access": "public"
}
}

2
pnpm-lock.yaml generated
View File

@@ -518,6 +518,8 @@ importers:
specifier: ^11.0.3
version: 11.0.3
packages/tiny: {}
tests/webpack:
dependencies:
'@mermaid-js/mermaid-example-diagram':

View File

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