fuzzyworld

nordic-skating / files / vite.config.ts

vite.config.ts

Blame: the commit that last changed each line · file · history

c90277fa 2026-10-09 Pavel Safronov1import { defineConfig } from 'vite'
bd311616 2026-10-10 Pavel Safronov2import { VitePWA } from 'vite-plugin-pwa'
c90277fa 2026-10-09 Pavel Safronov3import { qrcode } from 'vite-plugin-qrcode'
bcbc446b 2026-10-27 Pavel Safronov4import fuzzyworld from 'fuzzyworld-tools/vite'
c90277fa 2026-10-09 Pavel Safronov5
6/**
7 * Relative asset paths by default, so the same build works wherever Pages puts it:
8 * at https://<user>.gitlab.io/<project>/ or, with unique domains on, at the root of a
9 * generated domain. Set BASE to override. `??` would not catch BASE="", so `||`.
10 */
11const base = process.env.BASE || './'
12
13export default defineConfig({
14 base,
15 // `npm run dev` binds to every interface (--host) so a phone on the same Wi-Fi can
16 // open the app; this prints a scannable QR of that network URL alongside it.
bd311616 2026-10-10 Pavel Safronov17 plugins: [
bcbc446b 2026-10-27 Pavel Safronov18 fuzzyworld(),
bd311616 2026-10-10 Pavel Safronov19 qrcode(),
20 // What makes the app installable: a manifest that says what it is called and how it
21 // opens, and a service worker that keeps a copy of it, so that it opens with no
22 // network at all. Nothing in the app is fetched after that; the lake is computed.
23 VitePWA({
24 // A new version is taken up the next time the app is opened, without asking.
25 registerType: 'autoUpdate',
26 includeAssets: ['apple-touch-icon.png', 'favicon.png', 'favicon-dark.png'],
27 manifest: {
28 name: 'Nordic Skating',
29 short_name: 'Skating',
30 description: 'An endless skate over thin black ice that sings under every stride.',
31 // No browser bars, and no status bar where the phone allows that: only the lake.
32 display: 'fullscreen',
33 display_override: ['fullscreen', 'standalone'],
34 background_color: '#0b1a24',
35 theme_color: '#0b1a24',
36 // Relative, for the same reason as `base`: both resolve against the manifest's
37 // own address, so the installed app belongs to wherever it was deployed.
bcbc446b 2026-10-27 Pavel Safronov38 id: '.',
bd311616 2026-10-10 Pavel Safronov39 start_url: '.',
40 scope: '.',
41 icons: [
42 { src: 'icon-192.png', sizes: '192x192', type: 'image/png' },
43 { src: 'icon-512.png', sizes: '512x512', type: 'image/png' },
44 { src: 'icon-maskable-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
45 ],
46 },
1ee103b4 2026-10-11 Pavel Safronov47 // The pictures on the buttons are kept on the phone with the rest: without them
48 // named here they would be fetched, and missing with no network.
49 workbox: { cleanupOutdatedCaches: true, globPatterns: ['**/*.{js,css,html,png}'] },
bd311616 2026-10-10 Pavel Safronov50 // Not while developing: a service worker handing back yesterday's code is the last
51 // thing wanted there.
52 devOptions: { enabled: false },
53 }),
54 ],
c90277fa 2026-10-09 Pavel Safronov55 // Vite's static directory is `static/`, not the default `public/`, because GitLab
56 // Pages requires its artifact to be a directory named `public` — and `mv dist public`
57 // does not rename when `public/` already exists, it moves dist *inside* it.
58 publicDir: 'static',
59 build: {
60 target: 'es2022',
61 // Three.js alone is ~515 kB. Raise the threshold past it so the warning stays
62 // meaningful for chunks that are large by accident.
63 chunkSizeWarningLimit: 600,
64 },
65})