anvilsign in

collin/mahjong

master / vite.config.ts
1import { defineConfig, type Plugin } from 'vite'
2import react from '@vitejs/plugin-react'
3import { attachRooms } from './server/rooms.ts'
4
5// The room relay rides vite's own http server, so `npm run dev` (and
6// `npm run preview`) is the whole stack — the client finds it at /ws on the
7// same origin, exactly where server/index.ts puts it in production.
8const roomRelay = (): Plugin => ({
9 name: 'room-relay',
10 configureServer(s) {
11 if (s.httpServer) attachRooms(s.httpServer)
12 },
13 configurePreviewServer(s) {
14 if (s.httpServer) attachRooms(s.httpServer)
15 },
16})
17
18// https://vite.dev/config/
19export default defineConfig({
20 plugins: [react(), roomRelay()],
21 // Served happily from under any path, not just a domain root — so every
22 // built URL has to be relative to the page.
23 base: './',
24 // portless hands us PORT/HOST; vite doesn't read them on its own
25 server: {
26 port: process.env.PORT ? Number(process.env.PORT) : undefined,
27 // Every address, not just loopback. The QR on the table carries this
28 // machine's address on the wifi (see `lanAddress` in server/rooms.ts), and
29 // a link nothing is listening on is worse than no link at all.
30 host: process.env.HOST || true,
31 // Tunnels and LAN names have to get past vite's Host check, or every
32 // phone that scans the QR meets a 403.
33 allowedHosts: [
34 '.vibe.richardscollin.com', // rsgrok, the house tunnel (~/Code/ngrok)
35 '.ngrok-free.dev',
36 '.ngrok.app',
37 '.ngrok.dev',
38 '.local',
39 '.localhost',
40 ],
41 },
42})