diff --git a/.esbuild/build.ts b/.esbuild/build.ts index bee13af512..58f1504945 100644 --- a/.esbuild/build.ts +++ b/.esbuild/build.ts @@ -1,21 +1,49 @@ import { build } from 'esbuild'; import { mkdir, writeFile } from 'node:fs/promises'; -import { getBuildConfig } from './util.js'; +import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; import { packageOptions } from '../.build/common.js'; const shouldVisualize = process.argv.includes('--visualize'); const buildPackage = async (entryName: keyof typeof packageOptions) => { - await build(getBuildConfig({ entryName, minify: false })); - const { metafile } = await build( - getBuildConfig({ entryName, minify: true, metafile: shouldVisualize }) - ); - if (metafile) { - // Upload metafile into https://esbuild.github.io/analyze/ - await writeFile(`stats/meta-${entryName}.json`, JSON.stringify(metafile)); + const commonOptions = { ...defaultOptions, entryName } as const; + const buildConfigs = [ + // package.mjs + { ...commonOptions }, + // package.min.mjs + { + ...commonOptions, + minify: true, + metafile: shouldVisualize, + }, + // package.core.mjs + { ...commonOptions, core: true }, + ]; + + if (entryName === 'mermaid') { + const iifeOptions: MermaidBuildOptions = { ...commonOptions, format: 'iife' }; + buildConfigs.push( + // mermaid.js + { ...iifeOptions }, + // mermaid.min.js + { ...iifeOptions, minify: true, metafile: shouldVisualize } + ); + } + + const results = await Promise.all(buildConfigs.map((option) => build(getBuildConfig(option)))); + + if (shouldVisualize) { + for (const { metafile } of results) { + if (!metafile) { + continue; + } + const fileName = Object.keys(metafile.outputs) + .filter((file) => !file.includes('chunks') && file.endsWith('js'))[0] + .replace('dist/', ''); + // Upload metafile into https://esbuild.github.io/analyze/ + await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile)); + } } - await build(getBuildConfig({ entryName, minify: false, core: true })); - await build(getBuildConfig({ entryName, minify: true, format: 'iife' })); }; const handler = (e) => { @@ -26,9 +54,7 @@ const handler = (e) => { const main = async () => { await mkdir('stats').catch(() => {}); const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; - for (const pkg of packageNames) { - await buildPackage(pkg).catch(handler); - } + await Promise.allSettled(packageNames.map((pkg) => buildPackage(pkg).catch(handler))); }; void main(); diff --git a/.esbuild/server.ts b/.esbuild/server.ts index 32867ded4d..9a07a39216 100644 --- a/.esbuild/server.ts +++ b/.esbuild/server.ts @@ -1,21 +1,32 @@ import express from 'express'; import type { NextFunction, Request, Response } from 'express'; import cors from 'cors'; -import { getBuildConfig } from './util.js'; +import { getBuildConfig, defaultOptions } from './util.js'; import { context } from 'esbuild'; import chokidar from 'chokidar'; const mermaidCtx = await context( - getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }) + getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid' }) ); const mermaidIIFECtx = await context( - getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' }) + getBuildConfig({ + ...defaultOptions, + minify: false, + core: false, + entryName: 'mermaid', + format: 'iife', + }) ); const externalCtx = await context( - getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' }) + getBuildConfig({ + ...defaultOptions, + minify: false, + core: false, + entryName: 'mermaid-example-diagram', + }) ); const zenumlCtx = await context( - getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' }) + getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid-zenuml' }) ); const contexts = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx]; diff --git a/.esbuild/util.ts b/.esbuild/util.ts index 249045652d..a0b9bf7397 100644 --- a/.esbuild/util.ts +++ b/.esbuild/util.ts @@ -8,14 +8,21 @@ import { jisonPlugin } from './jisonPlugin.js'; const __dirname = fileURLToPath(new URL('.', import.meta.url)); -interface MermaidBuildOptions { +export interface MermaidBuildOptions { minify: boolean; - core?: boolean; - metafile?: boolean; - format?: 'esm' | 'iife'; + core: boolean; + metafile: boolean; + format: 'esm' | 'iife'; entryName: keyof typeof packageOptions; } +export const defaultOptions: Omit = { + minify: false, + metafile: false, + core: false, + format: 'esm', +} as const; + const buildOptions = (override: BuildOptions): BuildOptions => { return { bundle: true, @@ -32,24 +39,31 @@ const buildOptions = (override: BuildOptions): BuildOptions => { }; }; -export const getBuildConfig = ({ - minify, - core, - entryName, - metafile, - format, -}: MermaidBuildOptions): BuildOptions => { +const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => { + if (core) { + fileName += '.core'; + } else if (format === 'esm') { + fileName += '.esm'; + } + if (minify) { + fileName += '.min'; + } + return fileName; +}; + +export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { + const { core, entryName, metafile, format } = options; const external: string[] = ['require', 'fs', 'path']; const { name, file, packageName } = packageOptions[entryName]; + const outFileName = getFileName(name, options); let output: BuildOptions = buildOptions({ absWorkingDir: resolve(__dirname, `../packages/${packageName}`), entryPoints: { - [`${name}${core ? '.core' : format === 'iife' ? '' : '.esm'}${ - minify ? '.min' : '' - }`]: `src/${file}`, + [outFileName]: `src/${file}`, }, metafile, logLevel: 'info', + chunkNames: `chunks/${outFileName}/[name]-[hash]`, }); if (core) { diff --git a/cSpell.json b/cSpell.json index 727a41bc91..76ce8c52f0 100644 --- a/cSpell.json +++ b/cSpell.json @@ -94,6 +94,7 @@ "nikolay", "nirname", "orlandoni", + "outdir", "pathe", "pbrolin", "phpbb", diff --git a/packages/mermaid-zenuml/package.json b/packages/mermaid-zenuml/package.json index b907e2cbae..913cc708ec 100644 --- a/packages/mermaid-zenuml/package.json +++ b/packages/mermaid-zenuml/package.json @@ -19,6 +19,7 @@ "mermaid" ], "scripts": { + "clean": "rimraf dist", "prepublishOnly": "pnpm -w run build" }, "repository": {