-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.ts
More file actions
55 lines (45 loc) · 2.44 KB
/
Copy pathbuild.ts
File metadata and controls
55 lines (45 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env bun
// build.ts — concatenate src/*.js (in filename order) back into a single
// rogue-racer.html by substituting the // @@BUNDLE@@ marker in src/index.html.
//
// The game ships as ONE self-contained file (the self-updating loader
// document.write()s it). Edit files under src/, run `bun build.ts`, commit the
// regenerated rogue-racer.html. Do NOT hand-edit rogue-racer.html.
//
// No module system: the src/*.js files share one global scope, exactly like the
// original inline <script>. Numeric filename prefixes fix concatenation order.
import { readdir } from "node:fs/promises";
const MARKER = "// @@BUNDLE@@";
const OUT = "rogue-racer.html";
const shell = await Bun.file("src/index.html").text();
if (!shell.includes(MARKER)) {
throw new Error(`src/index.html is missing the ${MARKER} marker — cannot build.`);
}
const numPrefix = (f: string) => {
const m = f.match(/^(\d+)/);
if (!m) throw new Error(`src/${f} has no numeric order prefix (expected e.g. 05-foo.js)`);
return parseInt(m[1], 10);
};
const files = (await readdir("src"))
.filter((f) => f.endsWith(".js"))
.sort((a, b) => numPrefix(a) - numPrefix(b)); // order by numeric prefix, NOT lexicographically
if (files.length === 0) throw new Error("No src/*.js files found — nothing to bundle.");
const parts = await Promise.all(files.map((f) => Bun.file(`src/${f}`).text()));
// Files were emitted as slices of the original JS joined with "\n"; rejoining the
// file contents with "\n" reproduces the original inline JS byte-for-byte.
const js = parts.join("\n");
let out = shell.replace(MARKER, () => js); // function replacer: no $-substitution surprises
// Stamp a "generated — do not edit" banner right after the doctype, so anyone who
// opens rogue-racer.html directly is told to edit src/ instead. (This is the only
// intentional difference from the original single file.)
const BANNER =
"<!-- ============================================================\n" +
" GENERATED FILE — DO NOT EDIT.\n" +
" Built from src/ by `bun build.ts`. Edit files under src/ and\n" +
" run `bun run build` (or `bun run dev`). Hand edits here are\n" +
" overwritten on the next build.\n" +
" ============================================================ -->";
out = out.replace(/(<!DOCTYPE html>\r?\n)/i, `$1${BANNER}\n`);
await Bun.write(OUT, out);
console.log(`Bundled ${files.length} files -> ${OUT}`);
files.forEach((f, i) => console.log(` ${i + 1}. ${f}`));