// Client build: TypeScript (+ per-component .html/.css) -> client/dist, // via esbuild. Kept as a small hand-written script rather than a config // file for a heavier tool (Vite, webpack) - this app's whole client is a // couple thousand lines across a dozen files, esbuild's own bundling // (including its built-in "collect CSS imported from JS into a sibling // .css file" behavior) is all it needs, consistent with this project's // general bias against dependencies it doesn't need. // // Usage: node build.mjs [--watch] // npm run build -> one-off build (what server/Dockerfile's build stage runs) // npm run watch -> rebuilds on save, for local dev (see README's // Running locally section) import * as esbuild from 'esbuild'; import { copyFileSync, cpSync, mkdirSync } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const here = path.dirname(fileURLToPath(import.meta.url)); const outdir = path.join(here, 'dist'); mkdirSync(outdir, { recursive: true }); copyFileSync(path.join(here, 'src', 'index.html'), path.join(outdir, 'index.html')); // PWA manifest + icons (manifest.webmanifest, icons/*) - see // docs/architecture.md's "Progressive Web App" section. Copied wholesale // rather than named file-by-file like index.html above, so adding another // icon later needs no build.mjs change. cpSync(path.join(here, 'src', 'public'), outdir, { recursive: true }); const buildOptions = { entryPoints: [path.join(here, 'src', 'app.ts')], outfile: path.join(outdir, 'app.js'), bundle: true, format: 'esm', target: 'es2020', sourcemap: true, // Each component imports its own template as a raw string (`import html // from './Foo.html'`) - see global.d.ts. CSS imports need no loader // entry: esbuild bundles any CSS reached from a JS/TS entry point into a // sibling app.css automatically. loader: { '.html': 'text' } }; const watch = process.argv.includes('--watch'); if (watch) { const ctx = await esbuild.context(buildOptions); await ctx.watch(); console.log('[watchparty-client] watching for changes...'); } else { await esbuild.build(buildOptions); console.log('[watchparty-client] built to client/dist'); }