Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overriding HMR port with vite.server.hmr.port no longer working #3017

Closed
Conduitry opened this issue Dec 10, 2021 · 16 comments
Closed

Overriding HMR port with vite.server.hmr.port no longer working #3017

Conduitry opened this issue Dec 10, 2021 · 16 comments
Labels
bug Something isn't working vite
Milestone

Comments

@Conduitry
Copy link
Member

Describe the bug

If you specify the Vite config server.hmr.port to override the port that the websocket connection for HMR uses, Vite dev runtime code in the browser attempts to connect to this port but the connection fails, triggering repeated refreshes of the page.

Reproduction

From the starter template, add

vite: { server: { hmr: { port: 3001 } } }

to your svelte.config.js to set the https://vitejs.dev/config/#server-hmr setting.

Open the browser and look at the console and network tab.

Logs

[vite] connecting... client.ts:22:8
<Routes> received an unexpected slot "default". index.mjs:1983:20
Firefox can’t establish a connection to the server at ws://localhost:3001/. client.ts:28:15
[vite] server connection lost. polling for restart...

System Info

Node 17.2.0
Firefox 95.0

  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.3
    @sveltejs/kit: next => 1.0.0-next.201
    svelte: ^3.44.0 => 3.44.2

Severity

blocking an upgrade

Additional Information

This used to work, although I haven't chased down which version this broke in. (This would be inconvenient to do, because of all the other intended breaking changes that Kit has had in the past months.) The first place I'm going to look is the #1517 stuff though.

@Conduitry Conduitry added bug Something isn't working vite labels Dec 10, 2021
@Conduitry
Copy link
Member Author

I don't think this is related to #1517 anymore. It's probably more likely to be related to our now using the Vite dev server in SvelteKit dev mode - or else some other unrelated unexpected Vite change.

The merged config we're passing to Vite does include the expected server.hmr.port value. We're then calling await this.vite.listen(this.port); but I don't know what the corresponding code would be (if any) to tell Vite to start up its HMR websocket server as well. The vite object does have a ws object on it, but this does not appear to have any methods on it that would help us. Still digging.

@Conduitry
Copy link
Member Author

When I manually edit https://github.com/vitejs/vite/blob/2efc1e571ff6e80a16104c4cb0f888a38c0b30c9/packages/vite/src/node/server/ws.ts#L33 to include port: 3001 instead of noServer: true, this appears to work. I don't know what this suggests.

@Conduitry
Copy link
Member Author

It seems like we don't want createWebSocketServer getting called with the server argument, as it then tries to use that instead of starting its own WS server. Looking at how that function's called in https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/index.ts - do we need to enable middlewareMode so that createWebSocketServer is passed null instead of the HTTP server? What is middleware mode?

@JandosKh
Copy link

JandosKh commented Jan 2, 2022

The following worked for me. Use clientPort, not port.

kit: {
	adapter: adapter({
		fallback: "200.html"
	}),
	prerender: {
		enabled: false
	},
	ssr: false,
	vite: {
		server: {
			hmr: {
				clientPort: 7231
			}
		}
	}
}

@Conduitry
Copy link
Member Author

Thanks, I was able to make that work, although it was in conjunction with Docker and binding to the port that Vite was by default listening on. This appears to be a good enough workaround for me for now.

I'm tempted to leave this issue open though (rather than closing it in favor of the Vite issue I opened) because this isn't going to be an option for people who aren't using Docker or some other proxy/mechanism for mapping between ports. I'll leave the decision of whether to close this to the other maintainers.

@Rich-Harris Rich-Harris added this to the 1.0 milestone Mar 5, 2022
@benmccann
Copy link
Member

What is middleware mode?

Middleware mode means you bring your own Connect/Express/Polka server and run Vite as a middleware in that server. We did that at one point (which is probably when this worked as you expected), but now let Vite manage running its own Connect server.

I see that an issue was also opened in the Vite tracker and that this is reproducible without SvelteKit involved: vitejs/vite#6068

@benmccann
Copy link
Member

This has been fixed in Vite 2.9: vitejs/vite#7282

@Conduitry
Copy link
Member Author

@benmccann I have a pnpm.overrides.vite of "beta" and that's loading 2.9.0-beta.2, and I'm still seeing this issue. If I add the config I indicate in the OP, the browser is trying to connect to localhost:3001, but that request is timing out, and the page keeps refreshing.

@Conduitry Conduitry reopened this Mar 14, 2022
@Conduitry
Copy link
Member Author

I've also commented on vitejs/vite#6068 and that has been re-opened.

@benmccann
Copy link
Member

Sent a new fix, so I expect it to be addressed in 2.9. I'll close this one and use the Vite issue to track it

@techniq
Copy link
Contributor

techniq commented Mar 31, 2022

@benmccann Also running into this after upgrading to the latest released SvelteKit today. It was a pretty big jump from 202 to 303 I've been holding off until most of the recent breaking changes settled.

I see you pushed Upgrade to Vite 2.9 just a few hours ago that might fix this, and once SvelteKit 304 is pushed to npm, I'll give it a test.

My setup is a little different than @Conduitry as I have my dotnet backend (running on https://localhost:5443) proxying all calls to the SvelteKit/Vite server (http://localhost:3000) to not have to deal with CORS, handles HTTPS, etc.

Browser (accessing https://localhost:5443)
                    |
                    |
Backend (running on https://localhost:5443, also proxying http://localhost:3000)
                    |
                    |
SvelteKit (running on http://localhost:3000)

I currently use this setup in svelte.config.js (which also specifies the protocol of wss instead of ws). I'm not sure if I saw any mention of the protocol override still being handled, or if it's needed anymore.

vite: {
  server: {
    hmr: {
      protocol: 'wss',
      port: 5443,
    },
}

@Conduitry
Copy link
Member Author

SvelteKit and the Vite plugin depend on ^ semver ranges of Vite, so you should be able to get your package manager to just update Vite without upgrading SvelteKit, if you want to try this fix without doing the other changes that updating SvelteKit will require.

@techniq
Copy link
Contributor

techniq commented Mar 31, 2022

@Conduitry @benmccann Looks like I'm already on 2.9.1 after updating SvelteKit with 303 when I look in my package-lock.json

image

I also looked in node_modules/vite/package.json and saw the same thing...

image

so looks like Vite 2.9 didn't fix the issue. Not sure if it's the protocol: wss and/or the port: 5443 problem. I saw some people using port and clientPort but haven't quite figured if I can do that in my setup just yet.

@techniq
Copy link
Contributor

techniq commented Mar 31, 2022

I think I found the right combination to use this time (for Vite 2.9)...

vite: {
  server: {
    hmr: {
      protocol: 'ws',
      clientPort: 3000,
    },
}

for Vite 2.7 (what I had before), this worked...

vite: {
  server: {
    hmr: {
      protocol: 'wss',
      port: 5443,
    },
}

and prior to that I used:

vite: {
  server: {
    hmr: {
      protocol: 'ws',
      port: 3001,
    },
}

Can't say I know what I'm doing each time I upgrade Vite a minor release or two and it breaks HMR, but at least it works again :). Sorry for the noise but maybe this will help someone else in the future (I recall a few other SvelteKit issue threads with a lot of sharing configs / trial and error.

@literalsunbear

This comment was marked as duplicate.

@literalsunbear
Copy link

literalsunbear commented Jun 13, 2022

Letting you know that I spent like 3 hours this morning doing trial and error to make this work only to find through your comment (and gleaning from a couple others) that SvelteKit apparently forces Vite to try and establish a websocket connection to :3000 specifically. This is without a doubt one of the stupidest wild goose chases I've been on in quite some time.

To expand on your fix, I had to change the port in the docker configurations for my app to :3000. I'm going to do a little more experimentation later to see if I can get port forwarding figured out, but in the meantime this works. I just can't have any other applications living on :3000 in my docker instance for the time being I guess.

Thanks again, I was going crazy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working vite
Projects
None yet
Development

No branches or pull requests

6 participants