Eptagone / Vite.AspNetCore

Small library to integrate Vite into ASP.NET projects
MIT License
264 stars 35 forks source link

HMR proxy for ViteDevMiddleware #90

Closed sbakharev closed 8 months ago

sbakharev commented 9 months ago

Vite's docs state that:

With the default configuration, reverse proxies in front of Vite are expected to support proxying WebSocket. If the Vite HMR client fails to connect WebSocket, the client will fall back to connecting the WebSocket directly to the Vite HMR server bypassing the reverse proxies

If the server section is absent in vite.config.js then the fall back logic fails (tested in v5.0.10) - it retries connection using the "ws://localhost:undefined/" URI. As a result, enabling HMR currently requires explicit configuration:

export default defineConfig({
  server: {
    port: 5173,
    strictPort: true,
    hmr: {
      port: 5173,
    },
  },
}

This looks like a bug of Vite to me (I would have used the same default server port for HMR fall back), but I've anyway implemented the solution they describe as expected.

If a WebSocket request contains the appropriate subprotocol then ViteDevMiddleware delegates it to a minimalistic WS proxy ViteDevHmrProxy.

Unfortunately I haven't found any good method to check if UseWebSockets() has already been used during pipeline configuration, so I've also mentioned this call in READMEs.

sbakharev commented 9 months ago

I've edited my initial post multiple times after figuring out some details on how Vite and the middleware work but the idea to support WS proxying remains actual - you no longer need to configure the port in Vite settings.

Eptagone commented 8 months ago

Hi @sbakharev, could you also add an example project using websockets? I would like to analyze it in an example project.

sbakharev commented 8 months ago

Hi @Eptagone!

Sorry for my delayed response.

I've failed to reproduce the problem using existing basic examples. For some reason even when the server section is missing in vite.config, the HMR connection is anyway established directly - using actual Vite's port (not the port used by the dotnet app itself), thus bypassing the middleware (even the fallback logic not triggered). So I don't think it's worth adding a separate example into the source code, because the case my PR fixes seems to be somewhat specific.

I've made a very simple repro project: Vite.AspNetCore.BrokenHmr.zip

I'm new to all this so probably missing something. Hope you can figure out why it fails with HMR.

Steps:

Result:

Now if you use the code version with my fix then the WS connection would succeed with the first try and HMR would start working.

sbakharev commented 8 months ago

@Eptagone just interested. Have you figured out what was specific about my sample so it has been failing and other examples have not?