fastify / fastify-vite

Fastify plugin for Vite integration.
MIT License
826 stars 67 forks source link

Conflicting websockets between vite and `@fastify/websocket` causing infinite redirects #129

Open tcandens opened 6 months ago

tcandens commented 6 months ago

Prerequisites

Fastify version

4.24.3

Plugin version

5.0.6

Node.js version

20.x

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

22.04

Description

I have registered the plugin @fastify/websocket on my server and in development mode it is causing what is basically an infinite redirect when loading a page.

This appears to be due to how the @fastify/websocket plugin is attempting to handle the upgrade GET 101 which is being initiated by the vite HMR client on page loading. See this line in @fastify/websocket which is attempting to route any request upgrades on the server. https://github.com/fastify/fastify-websocket/blob/v8.3.1/index.js#L57

If I change @fastify/vite settings to not attach the HMR server to the current application server, it will correct this infinite redirect behavior.

# https://github.com/fastify/fastify-vite/blob/v5.0.6/packages/fastify-vite/mode/development.js#L18

  // Create and enable Vite's Dev Server middleware
  const devServerOptions = mergeConfig(
    defineConfig({
      configFile: false,
      server: {
        middlewareMode: true,
        hmr: {
-          server: this.scope.server
+ //         server: this.scope.server
+            port: 5137 // set distinct port just for debugging
        }
      },
      appType: 'custom'
    }),
    config.vite
  )

So it appears that the vite dev server has been configured to piggy back on the application server so that it can share https/http2 configurations. https://github.com/fastify/fastify-vite/commit/568e178a10768211944bfc1aaf6e57a6a091693d

That seems reasonable, but so does being able to easily use a plugin like @fastify/websocket and it seems reasonable for @fastify/websocket to handle upgrade requests for all requests against the application server to which it is attached, so I'm not sure what the best fix might be.

For my purpose it seems to work fine to add this to my projects vite.config.js

    server: {
        hmr: {
            server: false,
            port: 5173,
            clientPort: 5173,
        },
    },

false is not technically a valid option for vite.server.hmr.server but it will prevent the application server settings being merged in from @fastify/vite where as server: undefined will not.

With realtime applications being more and more common, having support for websockets would be very helpful so at the very least including a note on this behavior, I think, would be a good idea.

Happy to submit a PR once a direction is discussed.

Thanks!

Steps to Reproduce

You can check out this codesandbox for an example: Fastify Vite Kitchen Sink React Template

Expected Behavior

To be able to use blessed fastify plugins (like @fastify/websocket) on the application server without very special configuration settings.

trey-m commented 4 months ago

Is there a suggested workaround at the moment?