1import { defineConfig } from 'vite';
2import { execFileSync } from 'node:child_process';
3import { realpathSync } from 'node:fs';
4import { resolve } from 'node:path';
6/**
7 * Which build this is. It ends up in the URL the page hands out for the
8 * command line (src/main.ts), because npx keys its install directory on the
9 * whole spec string: the same URL keeps running whatever it first installed,
10 * however many times the file behind it has changed. A URL carrying the
11 * commit is a new spec, and so a fresh install.
12 */
13function buildId(): string {
14 if (process.env.GITHUB_SHA) return process.env.GITHUB_SHA.slice(0, 7);
15 try {
16 return execFileSync('git', ['rev-parse', '--short', 'HEAD'], {
17 cwd: import.meta.dirname,
18 encoding: 'utf8',
19 }).trim();
20 } catch {
21 return 'dev';
22 }
23}
25// numbl is a local `file:` dependency, so node_modules/numbl is a symlink to
26// the sibling checkout. Its package `exports` map only publishes the runtime
27// entry points, not the compiler internals we need (parser + JIT lowering), so
28// we reach them through a path alias. (package.json's `imports` field cannot
29// express this — Node rejects node_modules targets — and plain Node could not
30// resolve numbl's internal `.js`->`.ts` imports anyway, which is why the GPU
31// tests run in the browser harness rather than under `node`.)
32// Realpath'd through the symlink: dev serves modules under their real ids, so
33// aliasing the node_modules path would give the same file two identities (one
34// per spelling) and run its side effects twice — the interpreter's builtin
35// registry throws on the second.
36const numblSrc = realpathSync(resolve(import.meta.dirname, 'node_modules/numbl/src'));
38export default defineConfig({
39 base: './',
40 // The page is the browser build; the command line's bundle sets this true
41 // (vite.cli.config.ts). See src/cache/h5file.ts.
42 define: { __NODE_BUILD__: 'false', __BUILD_ID__: JSON.stringify(buildId()) },
43 resolve: {
44 alias: { 'numbl-src': numblSrc },
45 },
46 server: {
47 // the alias resolves outside the project root (through the symlink)
48 fs: { allow: [import.meta.dirname, numblSrc] },
49 },
50 build: {
51 target: 'es2022',
52 rollupOptions: {
53 // Two pages, deployed side by side: the single-solution page and the
54 // parameter sweep.
55 input: {
56 main: resolve(import.meta.dirname, 'index.html'),
57 sweep: resolve(import.meta.dirname, 'sweep.html'),
58 },
59 },
60 },
61});