clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

main
forge / demo / dev.ts
dev.ts 2.3K
1// npm run dev [-- <port>]: the demo forge on http://localhost:8080/ (after2// sh demo/make-demo.sh), rebuilt into _site/ when templates, assets, lib/ or3// the 11ty config change, and reloaded in open tabs. 11ty's own --serve4// can't do lib/: Node keeps the TypeScript modules it imported, so each5// build here is a new 11ty process, served by 11ty's dev server.6//7// It reads demo/root and writes only _site/ and .cache/dev/: no incremental8// build (FORGE_LIVE_WWW), no metrics or events in the demo's state.9import { spawn } from 'node:child_process';10import fs from 'node:fs';11import path from 'node:path';12import { createRequire } from 'node:module';13import { fileURLToPath } from 'node:url';1415interface DevServer {16 serve(port: number): void;17 reload(event: object): void;18}1920const app = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');21const port = Number(process.argv[2] || 8080);22const env: NodeJS.ProcessEnv = { ...process.env, FORGE_ROOT: path.join(app, 'demo/root'), FORGE_CACHE: path.join(app, '.cache/dev'), FORGE_METRICS: '0' };23delete env.FORGE_LIVE_WWW;24delete env.FORGE_WWW;25delete env.FORGE_ONLY;2627const require = createRequire(import.meta.url);28const server = (require('@11ty/eleventy-dev-server') as { getServer(name: string, dir: string, opts: object): DevServer })29 .getServer('forge', path.join(app, '_site'), {});3031// One build at a time; changes during a build queue one more.32let building = false;33let again = false;34function build(): void {35 if (building) {36 again = true;37 return;38 }39 building = true;40 const t = Date.now();41 const eleventy = spawn(process.execPath, [path.join(app, 'node_modules/.bin/eleventy'), '--config=eleventy.config.ts', '--quiet'], { cwd: app, env, stdio: 'inherit' });42 eleventy.on('exit', (code) => {43 building = false;44 if (code === 0) {45 console.log(`built in ${Date.now() - t}ms`);46 server.reload({});47 }48 if (again) {49 again = false;50 build();51 }52 });53}5455// Editors save in bursts; wait for a quiet moment.56let timer: ReturnType<typeof setTimeout> | undefined;57const changed = (): void => {58 clearTimeout(timer);59 timer = setTimeout(build, 100);60};61for (const p of ['site', 'lib', 'eleventy.config.ts']) fs.watch(path.join(app, p), { recursive: true }, changed);62build();63server.serve(port);