Closed mattiaz9 closed 2 years ago
Got the same problem on 2.3.7 as well. It can be reproduced if you have hmr.host set to localhost in your vite.config.js
...
server: {
hmr: {
protocol: 'ws',
host: 'localhost'
}
},
...
Solution: Remove the whole hmr key in your vite.config.js I personally think the host option doesn't make any sense.
it should be something like this:
...
server: {
hmr: {
protocol: 'ws',
port: 3000
}
},
...
@to vitejs devs: maybe on iOS, you should detect we've set localhost for hmr.host and prevent the flicking / constant page refresh / or ignore the hmr.host: 'localhost'.
The good news is that I got 15000 pageviews on Google Analytics in a few seconds, it make me feel my app is super successful ;-)
@dmx374 I haven't set hmr.host
. I tried with a blank vite + typescript + react project and got the same problem. The only params I set are server.https.key
& server.https.cert
.
I'm wondering if the certificate has something to do with it. I used the following command to crete it:
mkcert -key-file ssl/key.pem -cert-file ssl/cert.pem localhost
I can reproduce this locally in vite 2.4.3
with the latest versions of Safari, Google Chrome, and Microsoft Edge with a vanilla yarn create vite
(no react) altered by adding the following vite.config.ts
:
import { defineConfig, ConfigEnv } from 'vite';
export default defineConfig((_configEnv: ConfigEnv) => {
return {
server: {
port: 3000,
strictPort: true,
hmr: {
port: 9000
},
},
base: './'
}
});
Are y'all running your projects in docker containers? When I run the server in docker I experience this issue and hot reload is also broken. When I run the server locally, though, instead of in a container, I don't get this error and hot reload works as expected.
@mrweiner I personally don't, I run it locally.
@mrweiner My minimal reproduction involved no Docker containers, but I first experienced it in conjunction with Docker, which motivated me to find a minimal reproduction.
I'm having the same issue (vite 2.4.4). I run the vite server in a docker container, and use a reverse proxy to route the HTTPS traffic to this container. I already set server.hmr.clientPort: 443
, but the app keeps refreshing. I even tried server.hmr: false
to disable hmr entirely, still the same issue.
Also started having this problem, but only in Chrome, not in Firefox. Changing the various server.hmr
settings has no effect. I even downgraded to vite 2.1.5 but still the problem occurs. I think maybe Chrome made a change that causes the websocket to lose connection? Can anyone confirm this works in other browsers with default hmr settings?
Hi
Just chiming in, same issue, no proxy, no docker. Tested various server.hmr
combinations, including setting server.host to a named host (ie company.dev) with an associated certificate, added to the browser trusted list.
The websocket connection keeps failing. I am using current Edge but also tested in Chrome.
NB: all is well with same setup under HTTP.
Would you test your projects using vite@2.5.0-beta.1 ?
@patak-js I have the same problem described above and now I also get this error:
[vite] Internal server error: Unexpected token } in JSON at position 542
Plugin: vite:esbuild
File: /.../vite-project/src/main.tsx
I'm not sure what it could be.
Would you test your projects using vite@2.5.0-beta.1 ?
just tried it, still no luck.
UPDATE: tried 2.5.0-beta.2
, same issue
UPDATE: I was able to resolve the issue by setting the hmr.port
to 443 since my vite container is behind a SSL proxy. I thought it should be the hmr.clientPort
option, but obviously it was not. This works on both 2.4.4
and 2.5.0-beta.*
I was not able to resolve it with any of the suggestions. The only temporary fix was npm ci
and that only works until the first time hotreload is triggered. What's more, I am not having this problem in Firefox, only in Chrome on linux. Very confusing.
@pzmosquito can you please share your full config?
I've managed to get this to not reload. The WS never connects, but at least it doesn't reload and I can use non-built/non-minified JS/TS(x) files.
server: {
// host: '0.0.0.0',
// https: true,
hmr: {
host: 'ad345ds2.ngrok.io',
// port: 443,
// protocol: 'wss',
},
},
Uncommenting https
or port
makes Vite enter the endless reloading loop.
PS I'm using ngrok tunnel.
@pzmosquito can you please share your full config?
I've managed to get this to not reload. The WS never connects, but at least it doesn't reload and I can use non-built/non-minified JS/TS(x) files.
server: { // host: '0.0.0.0', // https: true, hmr: { host: 'ad345ds2.ngrok.io', // port: 443, // protocol: 'wss', }, },
Uncommenting
https
orport
makes Vite enter the endless reloading loop.PS I'm using ngrok tunnel.
import path from "path";
import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh";
export default defineConfig({
mode: "development",
resolve: {
alias: {
_: path.resolve(__dirname, "src"),
},
},
plugins: [
reactRefresh(),
],
clearScreen: false,
server: {
host: "0.0.0.0",
port: 3000,
strictPort: true,
hmr: {
port: 443,
},
},
});
In CodeSandbox traffic is routed to port 3000 from an SSL proxy on port 443. Vite will by default look for port 3000, instead of port 443. The only configuration needed to make it work was changing the HMR port.
server: {
hmr: {
port: 443
}
}
Working codesandbox: https://codesandbox.io/s/vite-hmr-fix-4259-h6c2l?file=/vite.config.ts:180-227
I tried all of the above solutions and finally found a solution that works for me. 🎉
Here's what works for me:
ngrok http 3000
localtunnel
npm package that I install globally: npm install -g localtunnel
localtunnel
to listen for WebSocket connections on port 3036: lt --port=3036
So in my case:
@vfonic what is the significance of port 3036 -- how did you determine or specify that it's for Vite's HMR traffic? What did you do with the tunnel URL produced by localtunnel? Maybe sharing your full config would help. Trying to better understand the setup for using Vite behind Ngrok.
@mattrossman that's the port that I've set the vite to run on in vite.json
:
{
"all": {
"sourceCodeDir": "app/javascript",
"watchAdditionalPaths": []
},
"development": {
"autoBuild": true,
"publicOutputDir": "vite-dev",
"port": 3036
},
"test": {
"autoBuild": true,
"publicOutputDir": "vite-test"
}
}
This is the default setup that vite_ruby
gem creates. I believe it's set to this port in order to avoid using the same port number that rails server
uses for backend.
I solved the problem,you need fix Charles -> SSL PRoxying Settings -> *:443
I experienced this same issue when building with docker. In the container my app runs on port 3000
, however, as I have another app running on that port on my local I am using 3001
as my host port. From my docker-compose.yml
for my Svelte+Vite app:
web-frontend:
build:
context: ./svelte-vite-frontend-dock
dockerfile: Dockerfile
volumes:
- ./svelte-vite-frontend-dock:/usr/src/app
- /usr/src/app/node_modules
ports:
- 3001:3000
- 24678:24678
Clues above in posts regarding people using reverse proxies made me realize that I needed to add this to my vite.config.js
file:
server: {
hmr: {
clientPort: 3001,
},
},
This immediately fixed my issue.
@pzmosquito can you please share your full config? I've managed to get this to not reload. The WS never connects, but at least it doesn't reload and I can use non-built/non-minified JS/TS(x) files.
server: { // host: '0.0.0.0', // https: true, hmr: { host: 'ad345ds2.ngrok.io', // port: 443, // protocol: 'wss', }, },
Uncommenting
https
orport
makes Vite enter the endless reloading loop. PS I'm using ngrok tunnel.import path from "path"; import { defineConfig } from "vite"; import reactRefresh from "@vitejs/plugin-react-refresh"; export default defineConfig({ mode: "development", resolve: { alias: { _: path.resolve(__dirname, "src"), }, }, plugins: [ reactRefresh(), ], clearScreen: false, server: { host: "0.0.0.0", port: 3000, strictPort: true, hmr: { port: 443, }, }, });
need to set strictPort=true, thanks a lot
There are two issues that talk about similar/the same issue. This one and Vite HMR is unusable behind reverse proxies with random port numbers for client.
I posted my config there, so here it is here as well:
Ahhh, well you could try my setup. It works, but uses two tunnels. Here's how I configured everything:
vite.config.ts
:
// ...
export default defineConfig({
// ...
server: {
hmr: {
host: `some-ngrok-subdomain.loca.lt`,
port: 443,
},
},
// ...
package.json
:
"devDependencies": {
"localtunnel": "2.0.1",
"ngrok": "^4.2.2"
}
And then I start everything:
./node_modules/.bin/lt --subdomain=some-ngrok-subdomain --port=3036
./node_modules/.bin/ngrok http -subdomain=some-ngrok-subdomain
Happy to report for gitpod.io
users who faced the same issue as the dev environments are likewise hosted in containers, changing the hrm.port
to 443
solved the issue immediately.
vite.config.ts:
// ...
export default defineConfig({
// ...
server: {
hmr: {
port: 443,
},
},
// ...
Edit: happy to report this works without specifying the host.
None of the methods mentioned here worked when using nginx
and localhost:3000
I think I got this working with NGINX (vite 2.7.1):
in your nginx config add an explicit mapping for the socket connection:
location /sockjs-node {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# And now all the stuff from above, again.
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host localhost;
proxy_set_header X-Forwarded-Server localhost;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
proxy_connect_timeout 90s;
proxy_read_timeout 90s;
proxy_send_timeout 90s;
}
then in the vite.config.js do something similar for the HMR section:
hmr: {
// Internal port (in container same as sveltekit port).
port: 8000,
host: "localhost",
// External port (Docker host)
clientPort: 8000,
path: "/sockjs-node/",
},
I also had to add this to the docker file running Vite (which I don't like, but seemed to work):
RUN mkdir node_modules/.vite
RUN chmod a+w node_modules/.vite
Thanks for the quick reply but it doesn't seem to work
Maybe related https://github.com/vitejs/vite/issues/6068
Hi,
I'm developing in localhost with Docker, and for me, the valid config is:
export default defineConfig({
server: {
host: true,
port: 5000
},
....
}
Or try to use ssl with mkcert (https://github.com/FiloSottile/mkcert#installation)
I hope it helps.
I'm quite sure this is not related to Docker nor ngrok. My app is running locally and I had the same issue- if I enable a CORS extension my app was constantly refreshing.
If you experience the same have a look into your web developer tools console logs and enable "Preserve logs" - you may see error messages like WebSocket connection to 'ws://localhost:xxxx/' failed.
What was working for me is to not open my app via "http://localhost:xxx..." but "http://127.0.0.1:xxx...." instead - no config change necessary.
If you don't like to use "http://127.0.0.1..." in your URL for some reason it may also work if you change your hmr config to use 127.0.0.1 as a specific host like this:
server: { hmr: { host: '127.0.0.1' } },
Same issue with Electron v17. Super annoying to debug as inside of Electron you cannot read the logs in the console because it constantly reloads. In the electron main process you only get something like:
[electron] [43218:0323/171253.916748:ERROR:ssl_client_socket_impl.cc(995)] handshake failed; returned -1, SSL error code 1, net_error -202
Took a while for me to connect this issue with the vite websocket. After commeting out the reload in the Vite client at the socket close listener, I could at least see the logs in the Electron renderer. Interestingly, changing the protocol in hmr: { protocol: 'ws' }
did not change the SSL error, it would fail to connect to ws://localhost:3000
all the same.
Using a valid certificate for vite, with the help of vite-plugin-mkcert
fixed the issue. So does app.commandLine.appendSwitch('ignore-certificate-errors');
in Electron.
The biggest issue is debugging this as initially there seems to be no indication this issue is connected to Vite without being able to see the console. I guess the root cause might be Electron, but maybe we can also do something to prevent endless reloading on Vite's site?
Because I wanted to achieve a local-to-git-to-codesandbox flow, here is how I got Vite working for both local development and CodeSandbox without the refresh issue.
1) Add an extra dev script with a new sandbox mode. I called it sandbox
:
"scripts": {
"dev": "vite --host",
"sandbox": "APP_ENV=sandbox vite",
"build": "vite build",
"preview": "vite preview"
},
2) Set vite.config.js to pick up on that accordingly (avoiding the clientPort from local dev):
{
server: process.env.APP_ENV === "sandbox" ? { hmr: { clientPort: 443 } } : {};
}
3) Create a codesandbox.config.json
config for the new startScript
:
{
"container": {
"startScript": "sandbox"
}
}
Working sandbox: https://codesandbox.io/s/react-three-fiber-vite-starter-r1tgld
I am experiencing this issue with 2.9.1
inside a docker container.
UPDATE:
This solved the issue for me, I changed hmr.port
to hmr.clientPort
in vite.config.js
Here is my git diff
hmr: {
- port: 14365
+ clientPort: 14365
}
@aflansburg https://github.com/vitejs/vite/issues/4259#issuecomment-999092118 Could you kindly be asked to post your entire docker-compose setup with Nginx conf, Node and latest SvelteKit working and its config with the Vite websockets ?
Likewise anyone else that works with a Docker environment and got the websockets working with a Node app through Nginx, it would be great to be able to have a look at how you have set up things to work, thank you.
@aflansburg #4259 (comment) Could you kindly be asked to post your entire docker-compose setup with Nginx conf, Node and latest SvelteKit working and its config with the Vite websockets ?
Likewise anyone else that works with a Docker environment and got the websockets working with a Node app through Nginx, it would be great to be able to have a look at how you have set up things to work, thank you.
Sure thing, this is my setup / config, hope this helps.
docker-compose.yaml
version: '3.7'
services:
# Node for client app
vue-symfony-scaffolding-client-node:
container_name: vue-symfony-scaffolding-client-node
build: docker/containers/client-node
restart: unless-stopped
stdin_open: true # Needed for HMR
environment:
- CHOKIDAR_USEPOLLING=true # Needed for HMR
ports:
- 14365:3000
volumes:
- ./app/client:/var/www
networks:
- app-network
# Nginx for server app
vue-symfony-scaffolding-server-nginx:
container_name: vue-symfony-scaffolding-server-nginx
build: docker/containers/server-nginx
restart: unless-stopped
ports:
- 13100:80
volumes:
- ./app/server:/var/www
- ./docker/containers/server-nginx/etc/nginx/conf.d:/etc/nginx/conf.d
depends_on:
- vue-symfony-scaffolding-server-php
- vue-symfony-scaffolding-server-mysql
networks:
- app-network
# PHP for server app
vue-symfony-scaffolding-server-php:
build: docker/containers/server-php
container_name: vue-symfony-scaffolding-server-php
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: php
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./app/server:/var/www
networks:
- app-network
depends_on:
- vue-symfony-scaffolding-server-mysql
# MySQL for server app
vue-symfony-scaffolding-server-mysql:
image: mysql:8.0
container_name: vue-symfony-scaffolding-server-mysql
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
tty: true
ports:
- "34472:3306"
volumes:
- dbdata:/var/lib/mysql/
environment:
MYSQL_ROOT_PASSWORD: wGgfBcJzfSer2mLgh5Na5QKaZ
MYSQL_DATABASE: vue_symfony_scaffolding
networks:
- app-network
# Node websocket server
vue-symfony-scaffolding-websocket:
container_name: vue-symfony-scaffolding-websocket
build: docker/containers/websockets
restart: always
stdin_open: true # Needed for HMR
environment:
- CHOKIDAR_USEPOLLING=true # Needed for HMR
ports:
- 46295:46295
volumes:
- ./websocket:/var/www
networks:
- app-network
# Networks
networks:
app-network:
driver: bridge
# Volumes
volumes:
dbdata:
driver: local
Here is my vite.config.ts:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'url'
import Components from 'unplugin-vue-components/vite'
export default defineConfig(({ command }) => {
return {
plugins: [
vue({ reactivityTransform: true }),
Components({}),
],
base: (command === 'build') ? './' : '/',
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@img': fileURLToPath(new URL('./src/assets/img', import.meta.url)),
},
},
server: {
host: true,
hmr: {
clientPort: 14365
}
}
}
})
And my Nginx config (these may not be the actual port numbers used):
server {
listen 80;
server_name app.booking-jojo.com;
client_max_body_size 100M;
location /ws/ {
proxy_pass http://localhost:46295;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://localhost:41166/;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://localhost:47344;
}
}
@aflansburg #4259 (comment) Could you kindly be asked to post your entire docker-compose setup with Nginx conf, Node and latest SvelteKit working and its config with the Vite websockets ?
Likewise anyone else that works with a Docker environment and got the websockets working with a Node app through Nginx, it would be great to be able to have a look at how you have set up things to work, thank you.
Hi sorry for the delay. My project is public monorepo and can be seen here. I haven't been able to work on it as of late, but essentially components are:
I experienced this same issue when building with docker. In the container my app runs on port
3000
, however, as I have another app running on that port on my local I am using3001
as my host port. From mydocker-compose.yml
for my Svelte+Vite app:web-frontend: build: context: ./svelte-vite-frontend-dock dockerfile: Dockerfile volumes: - ./svelte-vite-frontend-dock:/usr/src/app - /usr/src/app/node_modules ports: - 3001:3000 - 24678:24678
Clues above in posts regarding people using reverse proxies made me realize that I needed to add this to my
vite.config.js
file:server: { hmr: { clientPort: 3001, }, },
This immediately fixed my issue.
setting the clientPort if you using docker fix my issue
If anyone is interested, I am using Devilbox for local "remote" development and have thus everything in containers and the host is left clean. Here is an example setup with SvelteKit and NGINX proxy. https://github.com/robots4life/devilskit
Closing as https://github.com/vitejs/vite/pull/8650 covers most reported cases here. Please try 3.0.0-beta.1. If it is still not working with 3.0.0-beta.1, please create a discussion or a issue.
Describe the bug
In certain situation the app keeps refreshing indefinitely giving this log in console:
server connection lost polling for restart
.I'm using vite 2.4.2 with https, react and typescript.
Reproduction
I noticed this happen in this 2 situations:
vite
with the--host
flag and accessing it with my phone (Safari on iOS 14) via the shared url:https://192.168.1.xxx:3000
. Removing the https option "solves" the problem on iOS.System Info
Used Package Manager
yarn
Logs
No response
Validations