fix(vite): only skip vite-* WebSocket upgrades destined for Vite's HMR base#4291
fix(vite): only skip vite-* WebSocket upgrades destined for Vite's HMR base#4291pi0x wants to merge 1 commit into
Conversation
…R base
The dev-server upgrade handler skipped every upgrade whose subprotocol
started with `vite-`, to avoid colliding with Vite's HMR socket. But Vite
only claims an upgrade when the subprotocol is `vite-hmr`/`vite-ping` AND
the path equals its HMR base. The over-broad skip meant Nitro routes that
reverse-proxy an upstream Vite dev server never received the proxied HMR
upgrade — it hung in `pending`. Mirror Vite's exact claim condition
(protocol AND path) and account for `server.hmr.{server,port,path}` so we
don't defer when Vite isn't even listening on this server.
Includes a regression test (test/unit/vite-ws.test.ts).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Summary
In dev mode, Nitro's Vite integration installed an
upgradelistener that skipped every WebSocket upgrade whoseSec-WebSocket-Protocolstarted withvite-. The intent — don't fight Vite's own HMR socket — was right, but the condition was too broad: it keyed off the subprotocol alone and ignored the request path.As a result, a Nitro route that reverse-proxies an upstream Vite dev server never received the upstream's proxied HMR upgrade (
vite-hmron a non-HMR path): Nitro skipped it and outer Vite ignored it (wrong path), so the socket hung inpendingforever.Fix
Mirror Vite's own claim condition in
configureViteDevServer(src/build/vite/dev.ts): only defer to Vite when the subprotocol isvite-hmr/vite-pingand the request path equals Vite's resolved HMR base. Also account forserver.hmr.{server,port,path}— when HMR runs on a separate server/port, Vite attaches no listener here, so Nitro must not defer.Tests
test/unit/vite-ws.test.tsspins up a real Nitro+Vite dev server with a WebSocket handler on a non-HMR path and performs a rawvite-hmrupgrade handshake. It fails (hangs to timeout) on the old code and passes with the fix; a plain upgrade is covered as a control.pnpm typecheckandpnpm fmtare clean.🤖 Generated with Claude Code