SIGN IN SIGN UP

Answer a preview reached from another machine with a built bundle

A preview opened from a phone went through the dev server, which ships every
module unbundled: 2047 requests for an authorized boot, against 99 built, each
one a round trip over the network. Its HMR websocket does not survive a mobile
browser backgrounding the tab either - on return the Vite client pings until the
server answers and then calls location.reload(), throwing away whatever was
being tested.

The dev server now keeps HMR for localhost and answers anything that arrived
from elsewhere out of a built bundle, on the same port and from one command. The
proxy in front of a preview rewrites Host to a bare `localhost`, while a browser
on this machine always sends the port with it; ?static=1 forces the bundle here,
?static=0 forces the dev server from outside, and neither depends on the other
working.

The bundle is built lazily, so a desktop-only session pays nothing: the first
remote request spawns `vite build --watch` and gets a self-refreshing page for
~10s, after which an edit lands in ~7s and a refresh on the phone picks it up.
Rebuilds keep their predecessors, so a page that is mid-load cannot 404 on a
chunk that was just replaced; each page load then sweeps out the builds that are
both superseded and older than ten minutes, because a rebuild touching the entry
cascades new hashes through every chunk that imports it - some 40 MB a time. The
document is only served once its closing tag is on disk: rolldown writes
index.html in place, and a build killed mid-write leaves a blank page behind.

--static (and --watch, which adds the rebuild watcher) drop the dev server
entirely and serve only the bundle, for looking at the production output itself.
Hashed files go out immutable, the entry and the service worker never pinned.

Two things had to be kept out of the way:

- tsconfig excluded neither tmp/ nor the build now written into it. allowJs is
  on, and a build emits worker chunks with no import/export, so TS read them as
  classic scripts and their minified top-level names became globals - one of
  them shadowed vitest's `vi` and produced 1196 phantom errors across the test
  suite. The dep-optimizer cache under tmp/ was dragging 1515 files into every
  typecheck besides: 5029 files in the program before, 3222 after.
- the dev server watched tmp/ as well, so ANY preview's rebuild full-reloaded
  the pages of every dev server in the repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
E
Eduard Kuzmenko committed
567a3df2adab28ecd23eb30e6a9b847da362000e
Parent: d07eeea