mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
chore: Add live-reload
This commit is contained in:
parent
01b2f80a95
commit
9fb9bed806
@ -1,29 +1,84 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import type { NextFunction, Request, Response } from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { getBuildConfig } from './util.js';
|
import { getBuildConfig } from './util.js';
|
||||||
import { context } from 'esbuild';
|
import { context } from 'esbuild';
|
||||||
|
import chokidar from 'chokidar';
|
||||||
|
|
||||||
|
const mermaidCtx = await context(
|
||||||
|
getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })
|
||||||
|
);
|
||||||
|
const mermaidIIFECtx = await context(
|
||||||
|
getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' })
|
||||||
|
);
|
||||||
|
const externalCtx = await context(
|
||||||
|
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' })
|
||||||
|
);
|
||||||
|
const zenumlCtx = await context(
|
||||||
|
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' })
|
||||||
|
);
|
||||||
|
const contexts = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx];
|
||||||
|
|
||||||
|
const rebuildAll = async () => {
|
||||||
|
await Promise.all(contexts.map((ctx) => ctx.rebuild()));
|
||||||
|
};
|
||||||
|
|
||||||
|
let clients: { id: number; response: Response }[] = [];
|
||||||
|
function eventsHandler(request: Request, response: Response, next: NextFunction) {
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
Connection: 'keep-alive',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
};
|
||||||
|
response.writeHead(200, headers);
|
||||||
|
const clientId = Date.now();
|
||||||
|
clients.push({
|
||||||
|
id: clientId,
|
||||||
|
response,
|
||||||
|
});
|
||||||
|
request.on('close', () => {
|
||||||
|
clients = clients.filter((client) => client.id !== clientId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeoutId: NodeJS.Timeout | undefined = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debounce file change events to avoid rebuilding multiple times.
|
||||||
|
*/
|
||||||
|
function handleFileChange() {
|
||||||
|
if (timeoutId !== undefined) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
timeoutId = setTimeout(async () => {
|
||||||
|
await rebuildAll();
|
||||||
|
sendEventsToAll();
|
||||||
|
timeoutId = undefined;
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendEventsToAll() {
|
||||||
|
clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
|
||||||
|
}
|
||||||
|
|
||||||
async function createServer() {
|
async function createServer() {
|
||||||
const app = express();
|
const app = express();
|
||||||
const mermaidCtx = await context(
|
chokidar
|
||||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })
|
.watch('**/src/**/*.{js,ts,yaml,json}', {
|
||||||
);
|
ignoreInitial: true,
|
||||||
const mermaidIIFECtx = await context(
|
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
|
||||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' })
|
})
|
||||||
);
|
.on('all', async (event, path) => {
|
||||||
const externalCtx = await context(
|
// Ignore other events.
|
||||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' })
|
if (!['add', 'change'].includes(event)) {
|
||||||
);
|
return;
|
||||||
const zenuml = await context(
|
}
|
||||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' })
|
console.log(`${path} changed. Rebuilding...`);
|
||||||
);
|
handleFileChange();
|
||||||
|
});
|
||||||
mermaidCtx.watch();
|
|
||||||
mermaidIIFECtx.watch();
|
|
||||||
externalCtx.watch();
|
|
||||||
zenuml.watch();
|
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
app.get('/events', eventsHandler);
|
||||||
app.use(express.static('./packages/mermaid/dist'));
|
app.use(express.static('./packages/mermaid/dist'));
|
||||||
app.use(express.static('./packages/mermaid-zenuml/dist'));
|
app.use(express.static('./packages/mermaid-zenuml/dist'));
|
||||||
app.use(express.static('./packages/mermaid-example-diagram/dist'));
|
app.use(express.static('./packages/mermaid-example-diagram/dist'));
|
||||||
|
@ -30,5 +30,33 @@ graph TB
|
|||||||
console.log(svg);
|
console.log(svg);
|
||||||
el.innerHTML = svg;
|
el.innerHTML = svg;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Set to false to disable live reload
|
||||||
|
const liveReload = true;
|
||||||
|
// Connect to the server and reload the page if the server sends a reload message
|
||||||
|
const connectToEvents = () => {
|
||||||
|
const events = new EventSource('/events');
|
||||||
|
const loadTime = Date.now();
|
||||||
|
events.onmessage = (event) => {
|
||||||
|
const time = JSON.parse(event.data);
|
||||||
|
if (time && time > loadTime) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
events.onerror = (error) => {
|
||||||
|
console.error(error);
|
||||||
|
events.close();
|
||||||
|
// Try to reconnect after 1 second in case of errors
|
||||||
|
setTimeout(connectToEvents, 1000);
|
||||||
|
};
|
||||||
|
events.onopen = () => {
|
||||||
|
console.log('Connected to live reload server');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (liveReload) {
|
||||||
|
connectToEvents();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"git graph"
|
"git graph"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "pnpm build:esbuild && pnpm build:types",
|
"build": "pnpm run -r clean && pnpm build:esbuild && pnpm build:types",
|
||||||
"build:esbuild": "pnpm run -r clean && ts-node-esm --transpileOnly .esbuild/build.ts",
|
"build:esbuild": "pnpm run -r clean && ts-node-esm --transpileOnly .esbuild/build.ts",
|
||||||
"build:mermaid": "pnpm build:esbuild --mermaid",
|
"build:mermaid": "pnpm build:esbuild --mermaid",
|
||||||
"build:viz": "pnpm build:esbuild --visualize",
|
"build:viz": "pnpm build:esbuild --visualize",
|
||||||
@ -82,6 +82,7 @@
|
|||||||
"@vitest/spy": "^0.33.0",
|
"@vitest/spy": "^0.33.0",
|
||||||
"@vitest/ui": "^0.33.0",
|
"@vitest/ui": "^0.33.0",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
"concurrently": "^8.0.1",
|
"concurrently": "^8.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cypress": "^12.10.0",
|
"cypress": "^12.10.0",
|
||||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -74,6 +74,9 @@ importers:
|
|||||||
ajv:
|
ajv:
|
||||||
specifier: ^8.12.0
|
specifier: ^8.12.0
|
||||||
version: 8.12.0
|
version: 8.12.0
|
||||||
|
chokidar:
|
||||||
|
specifier: ^3.5.3
|
||||||
|
version: 3.5.3
|
||||||
concurrently:
|
concurrently:
|
||||||
specifier: ^8.0.1
|
specifier: ^8.0.1
|
||||||
version: 8.0.1
|
version: 8.0.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user