-
-
Notifications
You must be signed in to change notification settings - Fork 8
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
feat(middleware-mode): single server for http and websocket #16
feat(middleware-mode): single server for http and websocket #16
Conversation
Thanks! Would you add a test for the original one (one without the
There are some cons of SSE. Recently esbuild implemented a live reload feature and described about these. https://github.com/evanw/esbuild/releases/tag/v0.17.0#:~:text=The%20EventSource%20API,itself%20(see%20below). WebSocket connections have a different connection pool from the normal HTTP connections. (https://stackoverflow.com/a/26013035) So by using WebSockets, we can effectively use the 6 connections to serve the JS/CSS files from Vite. |
Thanks @sapphi-red, now I added a new test case "middleware-mode-with-separated-vite" in cf19771, which replicates the behavior of the original one (simplified a little like removing For the comment about SSE: Thanks for sharing, especially an attempt in esbuild. Really interesting and now feeling it's not worth exploring much for Vite. Ooccupying 1 connection out of the precious 6 connections are really bad... |
Thanks for adding the test case. I updated the README image. |
This comes from vitejs/vite#11487
I think we should utilize Vite's ability to reuse an existing HTTP server for WebSocket for middleware-mode example in this repo.
I consider Vite's middleware mode's very important feature is to be able to rely on single HTTP server for everything including HMR.
The server can:
I think this repo is a perfect place to demonstrate / advertise this useful pattern with minimal example.
One of the reasons why I like this setup and why I think we should advertise more is because this setup is simpler than others and more composable than others with other configurations such as reverse proxy.
As long as reverse proxy supports proxing WebSocket, the simplest set up
Custom Server <-> Proxy <-> Browser
is possible. There is no need to make sure browser can talk to Vite's hard-coded port (24678
) for HMR.Also, TCP port is shared resource. With this setup, users of this server can just choose one port and it will just work without causing conflicts with other local dev servers in the same host.
If this looks good for maintainers, we can merge this after merging vitejs/vite#11487 since the test in this PR is failing due to "a bug" fixed there
Verification
Before this PR, HMR in
examples/middleware-mode
was working via the hard-coded24678
port, which means it was not possible to run multiple instances simultaneously on the same host. Also if there is proxy-ish thing which only allows single port to be relayed (e.g. SSH port forward and/or HTTP reverse proxy), this setup was not working out of the box.After this PR with vitejs/vite#11487, it will always try to connect to the "current server", which means it will always work even the server is hidden under reverse proxy and Vite server itself is not reachable (e.g. due to firewall or SSH port forward)
The following screenshot is taken with the Vite PR, where we see WebSocket is using the same port as the main URL:
Other considerations
I added
base
config to vite.config.js because without this, Vite client will try to connect to/
for WebSocket HMR. Considering this is an example of "custom server", I think this is not reasonable since the owner of the custom server should be able to freely use that "root namespace" for WebSocket. I think it makes sense to have "proper namespacing" even for this minimal example. Vite should not "occupy" the root name space ("/")If this is acceptable, we need to update the diagram in README.md as well. It will look like the following (this diagram visually shows the simplicity of the new config hopefully; browser does not need to know Vite, which is "abstracted away" by custom server, which is fully controlled by integrators):
"Direct websocket connection fallback" does not work as expected with this setup but I personally think it's fine. For this setup, it's user's responsibility to make sure browsers can connect to the custom server for WebSocket
(completely out of scope but I'm thinking whether it's possible to use Server Sent Events instead of WebSocket for further simplification for Vite HMR setup (e.g. some corporate proxy can block WebSocket)...)