#!/usr/bin/env node // Bundles dashboard/client/main.ts into build/dashboard/dashboard.html as a // single self-contained file. import { readFileSync, writeFileSync, mkdirSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, resolve } from 'path'; import * as esbuild from 'esbuild'; const here = dirname(fileURLToPath(import.meta.url)); const root = resolve(here, '..'); const outDir = resolve(root, 'build/dashboard'); mkdirSync(outDir, { recursive: true }); const debug = process.argv.includes('--debug'); const result = await esbuild.build({ entryPoints: [resolve(here, 'client/main.ts')], bundle: true, platform: 'browser', format: 'esm', minify: !debug, sourcemap: debug ? 'inline' : false, write: false, tsconfig: resolve(root, 'tsconfig.client.json'), }); if (debug) { const dbgJs = result.outputFiles[0].text; console.log('Symbol("target") occurrences (>1 means duplicate Aberdeen):', (dbgJs.match(/Symbol\("target"\)/g) || []).length); } if (result.errors.length) { for (const e of result.errors) console.error(e.text); process.exit(1); } const js = result.outputFiles[0].text; const template = readFileSync(resolve(here, 'client/index.html'), 'utf8'); const scriptTag = ``; // Use a function replacer so $& / $' / $` in the bundle are never treated as // special replacement patterns by String.replace. const html = template.replace('', () => scriptTag); const outFile = resolve(outDir, 'dashboard.html'); writeFileSync(outFile, html); console.log(`Dashboard bundled: ${outFile} (${(html.length / 1024).toFixed(1)} KB)`);