create-react-app
create-react-app copied to clipboard
WebSocket connection to 'ws://localhost:3000/ws' failed:
Basic React App doesn't work because the websocket connection appears to be hardcoded to port 3000. Part of this appears to be related to running in a container, but I've discovered additional issues even when running local.
Example project here - https://github.com/Fosol/bug-hot-reload
npm: 7.24.0 yarn: 1.22.5 node: v16.10.0 react-scripts: 5.0.0
I have cleared node_modules and performed all the mentioned steps.
Error message here.
WebSocket connection to 'ws://localhost:3000/ws' failed:
If I use port 3000
the error disappears, but nothing works.
Environment
System: OS: Windows 10 10.0.19044 CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor Binaries: Node: 16.10.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 7.24.0 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 96.0.4664.110 Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.57) Internet Explorer: 11.0.19041.1202 npmPackages: react: 17.0.2 => 17.0.2 react-dom: 17.0.2 => 17.0.2 react-scripts: 5.0.0 => 5.0.0 npmGlobalPackages: create-react-app: Not Found
Steps to reproduce
- Clone repo - https://github.com/Fosol/bug-hot-reload
- Run command
docker-compose up -d
- Open browser http://localhost:5000
Expected behavior
Application should work and hot reload should work.
Actual behavior
Application doesn't work and hot reload doesn't work. Additionally, it requires rebuilding the image to get any changes. A refresh doesn't work.
Reproducible demo
Repo here - https://github.com/Fosol/bug-hot-reload
If you change the default port from 5000
to 3000
the error goes away, but the site doesn't work at all. Even manual refreshing the page doesn't work. You have to rebuild the container for it to get any changes.
I've reduced the dependencies in a hope it narrows down the issue.
Running into the same problem I think it might be related to #11762
I don't have HOST
or proxy
defined in the example project.
Right now I can get it working locally (not in a container) if I add the following line of code to the index.tsx
file.
However when I attempt to load it in a container I get errors related to the testing libraries not working for some reason.
window.process = {} as any;
I don't have
HOST
orproxy
defined in the example project.
I was mostly referring to this comment, not assuming that you are using HOST
or proxy
. There appears to be a bug with how webpackDevSever.js
is initializing hosts which could be causing the issue that we're both experiencing.
Are you port mapping to non-standard ports within your container?
I am using a non-standard port to connect to the container, but inside the container it is still 3000. However, even when I changed the port to 3000 outside the container it doesn't work. It just doesn't throw the websocket connection anymore.
My latest attempts as stated above work locally, but not in the container. However, with my latest changes the container fails for a different reason. It complains of missing testing libraries... Which of course they are not missing and it works fine locally.
TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.
I'm having the same problem.
I've updated my repo. I've included the fix for local development. But it doesn't work for container development.
I've had no luck resolving this issue... Anyone else found a solution?
I'm using asp.net core 5 as my backend, I have the same message when I try to proxy my react app. The issue appeared after I've been upgrading packages to react 17.0.2 and react-router-dom to v6, not sure which caused it. (also noticed that every build is using different port for wss connection)
I'd love to know any solution to that
@Fosol I took a quick look yesterday, but no luck - feel free to help debug etc. I'll post if I get closer to figuring it out - also looking at #11762 they could be related/or not. (I'm a bit on/off + holidays are getting closer so any help appreciated :christmas_tree: :gift:)
Will have to look into WDS changelog again (they have been changing the configuration schema quite a bit) - maybe have to dig into CRA v4 behavior before figuring out the root cause.
We could likely treat the symptom by setting the WDS_SOCKET_PORT=5000
but would expect that to be set automatically...(I vaugly remember :older_man: something about the client defaulting to window.location.href
if some value was not set, should be in the wds source code - might be a value named something like "public" :thinking:)
~@Fosol If you set the environment variable WDS_SOCKET_PORT="location"
does it then work as expected? (If so we might want to set default values for sockPort etc. in the webpackDevServer.config.js
ref WDS docs)~
I have the same problem. I upgraded my react-scripts from v4 to v5 and I lost hot reload.
Here's my tech stack:
- Ubuntu
- Nginx
- Docker
- React
- mkcert
I use mkcert
to create valid local certificates. Then instead of localhost:3000
, I use hosts
file to create a DNS record for my project. Thus I develop using https://project.local
domain.
And I use nginx as a reverse proxy and here's my nginx config file:
server {
listen 80;
server_name project.local;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name project.local;
ssl_certificate /Temp/Project/AdminPanel/Certificate.pem;
ssl_certificate_key /Temp/Project/AdminPanel/Key.pem;
error_page 502 /502.html;
location /502 {
root /Temp/Project/AdminPanel/Nginx;
internal;
}
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
It was working great. But when I upgraded my react-scripts
from v4 to v5, it now complains that:
WebSocketClient.js:13 WebSocket connection to 'wss://project.local:3000/ws' failed:
WebSocketClient @ WebSocketClient.js:13
initSocket @ socket.js:17
(anonymous) @ socket.js:38
What should I change to fix this?
I was able to work around this issue by manually specifying the port used in my .env
file:
WDS_SOCKET_PORT=443
See https://create-react-app.dev/docs/advanced-configuration/#:~:text=for%20more%20details.-,WDS_SOCKET_PORT,-%E2%9C%85%20Used
For me WDS_SOCKET_PORT
can not be set statically. Because we have a system that dynamically assigns a port to our Nginx reverse proxy to bind to docker's 3000.
Using the WDS_SOCKET_PORT
environment variable appears to resolve the issue. Thanks for discovering this!
I still believe it's a bug because it should default to the port of the current window.location for ws connection.
Definitely a bug that needs fixing or thorough documentation. It's a minimum a breaking change...
It is indeed a bug. We dynamically assign ports. Inside docker react runs on port 3000. That 3000 would be mapped to a dynamic port on the host. Say 5694 or 34863. This way we can run many react docker instances all at the same time. Each would be mapped to the corresponding react docker via Nginx reverse proxy. We also work with mkcert
to create valid local certificates and we also use /etc/hosts
to register local DNS records.
You can imagine that when we develop, we access these URLs, all of which are react applications:
- https://project.local
- https://admin.project.local
- https://user.project.local
- https://blog.project.local
Its a bug, not a breaking change (its a bug in the webpack or wds config in CRA - Its one config url we need to remove just need to remember which one...)
WDS_SOCKET_PORT=0 Will use window location, still think its a misconfig in CRA but I'll check history in wds server to look for other clues
@raix, WDS_SOCKET_PORT=0
worked for me. But we still need it to be the default value and automatic. Because it's very repetitive to add this config to every .env
file of all projects.
However, you saved us for now. Thank you so much.
Now there is no connection error with WDS_SOCKET_PORT=0, but hot reload still doesn't work for me. I'm running app in docker container (port 3050) and using nginx.
Nginx default.conf:
upstream client {
server client:3000;
}
upstream api {
server api:3001;
}
server {
listen 80;
location / {
proxy_pass http://client;
}
location /ws {
proxy_pass http://client;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
}
}
docker-compose.yml:
version: '3.8'
services:
nginx:
depends_on:
- api
- client
restart: always
build:
dockerfile: Dockerfile
context: ./nginx
ports:
- '3050:80'
client:
stdin_open: true
environment:
- CHOKIDAR_USEPOLLING=true
- WDS_SOCKET_PORT=0
build:
dockerfile: Dockerfile
context: ./client
volumes:
- ./client/src:/app/src
Can anyone help?
Can anyone help?
Try
location /ws { proxy_pass http://client:3000; .......... }
Can anyone help?
Try
location /ws { proxy_pass http://client:3000; .......... }
Unfortunately it didn't help (
I was facing the same issue, but with WDS_SOCKET_PORT=0
it worked for me. No web socket error in the console anymore and hot reload also working.
My default.conf currently looks like this:
upstream frontend {
server client:3000;
}
upstream backend {
server api:5000;
}
server {
listen 80;
location / {
proxy_pass http://frontend;
}
location /ws {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://backend;
}
}
My docker-compose file looks like this:
version: '3'
services:
client:
build:
dockerfile: Dockerfile.dev
context: ./client
volumes:
- /app/node_modules
- ./client:/app
environment:
# Fixes bug where websocket connection is fixed to default port 3000
- WDS_SOCKET_PORT=0
... other services
I was facing the same issue, but with
WDS_SOCKET_PORT=0
it worked for me. No web socket error in the console anymore and hot reload also working.My default.conf currently looks like this:
upstream frontend { server client:3000; } upstream backend { server api:5000; } server { listen 80; location / { proxy_pass http://frontend; } location /ws { proxy_pass http://frontend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /api { rewrite /api/(.*) /$1 break; proxy_pass http://backend; } }
My docker-compose file looks like this:
version: '3' services: client: build: dockerfile: Dockerfile.dev context: ./client volumes: - /app/node_modules - ./client:/app environment: # Fixes bug where websocket connection is fixed to default port 3000 - WDS_SOCKET_PORT=0 ... other services
On which system are you running the project? I don't have hot reload on windows 10. On macOS everything works with the same config.
With WDS_SOCKET_PORT=0
the websocket connection and hot reload is working again on ASP.Net Core 6 on Windows 10.
On which system are you running the project? I don't have hot reload on windows 10. On macOS everything works with the same config.
Sorry, I did not get its about Windows. I am using macOS
I tried the WDS_SOCKET_PORT
setting with both 0 and 443 and neither made a difference. Hot Reload is still NOT working for me
If you're using Windows WSL you have to place your code within a WSL distro. If you have it on a Windows drive it won't work anymore, even with the WDS_SOCKET_PORT=0 workaround.
I was having the same problem from the websocket hardcoding the port, and adding WDS_SOCKET_PORT=0
to .env.local
solved it. My setup is something similar with nginx proxying everything and adding https support.
Now there is no connection error with WDS_SOCKET_PORT=0, but hot reload still doesn't work for me. I'm running app in docker container (port 3050) and using nginx.
Nginx default.conf:
@alexilin83
you're renaming the upstream variable client
to itself. try setting a different variable or hard-code the IP so you turn
upstream client {
server client:3000;
}
into
upstream client {
server 127.0.0.1:3000; # or something that's not "client"
}
the same goes for the api
variable
if it still doesn't work, try checking the chrome dev console under the console and the network tab
I am experiencing the same issue on my current project and I found a workaround.
In my dev env, I'm using a CRA in a docker context, with Traefik as a reverse proxy. There is 2 apps : a legacy Angular app, and a React app. Traefik redirects traffic in accordance with path prefix : v2
to React app, Angular otherwise :
Here how I handled it in react-scripts
4.x :
- I defined the path prefix in my React app using the
homepage: "v2"
field in thepackage.json
. - In Traefik, I put a rule to redirect prefixed urls to React.
- To work with Webpack Dev Server & hot reloading, I set an env var :
WDS_SOCKET_PATH=/v2/sockjs-node
With react-scripts
5.0.0, I need to do two changes:
- Specify an other env var :
WDS_SOCKET_PORT=0
because the React app no longer uses the default app port (80 thanks to Traefik): it was trying to access websocket through the port 3000. - Add a new Traefik rule redirecting all trafic on
/ws
path to the React App and removeWDS_SOCKET_PATH
env var to use default value (/ws
).
I think it is due to an issue introduced in 5.0.0 : DevServer WS does not use the specified path prefix inpackage.json
. This can be very annoying if you have several React application using Webpack Dev Server WS.
I can perform additional tests if you want.
Same issue with identical packages, but error message is
WebSocketClient.js:16 WebSocket connection to 'ws://localhost:3084/ws' failed: Invalid frame header
so the connection itself seems to be established and I can see in network tab in Chrome selecting request to "ws"
{"type":"hot"}
{"type":"liveReload"}
{"type":"reconnect","data":10}
{"type":"overlay","data":{"errors":true,"warnings":false}}
{"type":"hash","data":"89c4f09f2b82addd303a"}
{"type":"ok"}
Invalid frame header
Connection is established via dev server and http-proxy-middleware configured as follows
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = app => {
app.use(
['/api/**', '/ui'],
createProxyMiddleware({
target: 'http://localhost:8084',
ws: true,
changeOrigin: true,
cookieDomainRewrite: 'localhost:3084',
cookiePathRewrite: '/',
})
);
};
The identical configuration is working with react-scripts 4.0.3.
I had the same problem after upgrading react-scripts
from v4 to v5. Adding WDS_SOCKET_PORT=0
to the environment did solve the issue.
~~The suggestion workarounds do not work when the webpack-dev-server is behind a proxy which uses https. There does not seem to be a way to set the "scheme" to wss
.~~
A very easy solution would be to also expose https://webpack.js.org/configuration/dev-server/#websocketurl in the react-scripts configuration (similar to the other WDS_ variables at https://github.com/facebook/create-react-app/blob/20edab4894b301f6b90dad0f90a2f82c52a7ac66/packages/react-scripts/config/webpackDevServer.config.js#L20-L22).
For me, also in development the c-r-a app runs on https to avoid suprises with service workers and other things which behave differently when used secure.
To get protocol/hostname/port from browser one could then use auto://0.0.0.0:0/ws
.
Update
With
WDS_SOCKET_HOST=0.0.0.0
WDS_SOCKET_PORT=0
does get all values from the browser and magically also switches to wss
scheme when https is in use. So no action required.
It still doesn't work for me. Any progress on this?
From what I've seen, @sylvainDNS is correct in his comment: webpack-dev-server
does not respect PUBLIC_URL
when starting the hot refresh socket. In proxied environments (e.g. multi-frontend with Traefik in front, routing on sub-URLs) it's not possible to just redirect /ws
to a frontend, since there might be several frontends in simultaneous development.
While we are waiting for a solution, I've fell back to craco
. Yes, craco
is officially not supported for CRA 5.x and Webpack 5, however, it still works quite well for rewriting webpack-dev-server
's configuration. I've made it work with the following configuration:
module.exports = {
devServer: devServerConfig => {
devServerConfig.webSocketServer = {
options: { path: process.env.PUBLIC_URL + 'ws' }
};
return devServerConfig;
}
};
Hope this helps.
For me it seemed that just adding
WDS_SOCKET_PORT=0
to me .env
file was enough.
Since my website is in a reverse proxy adding
WDS_SOCKET_PORT=0
to .env
didn't work.
I needed to instead pass
WDS_SOCKET_PORT=443
I figured it out because trying to go to https://my.domain:3000/ws
gave me a could not connect, but https://my.domain:443/ws
worked.
for me adding
WDS_SOCKET_HOST=0.0.0.0
WDS_SOCKET_PORT=0
to the .env file is what fixed it
Facing the same issue, even in my simple deployed web app. Somebody may help please. I added this, and tried the above snippets too, in my .env
file but to no avail
REACT_APP_WDS_SOCKET_HOST=0.0.0.0
REACT_APP_WDS_SOCKET_PORT=0
@7527e Update: I actually had to delete the .env file because it broke again.
It needs that file 50% of the time lol
I am experiencing the same issue on my current project and I found a workaround.
In my dev env, I'm using a CRA in a docker context, with Traefik as a reverse proxy. There is 2 apps : a legacy Angular app, and a React app. Traefik redirects traffic in accordance with path prefix :
v2
to React app, Angular otherwise :Here how I handled it in
react-scripts
4.x :
- I defined the path prefix in my React app using the
homepage: "v2"
field in thepackage.json
.- In Traefik, I put a rule to redirect prefixed urls to React.
- To work with Webpack Dev Server & hot reloading, I set an env var :
WDS_SOCKET_PATH=/v2/sockjs-node
With
react-scripts
5.0.0, I need to do two changes:
- Specify an other env var :
WDS_SOCKET_PORT=0
because the React app no longer uses the default app port (80 thanks to Traefik): it was trying to access websocket through the port 3000.- Add a new Traefik rule redirecting all trafic on
/ws
path to the React App and removeWDS_SOCKET_PATH
env var to use default value (/ws
). I think it is due to an issue introduced in 5.0.0 : DevServer WS does not use the specified path prefix inpackage.json
. This can be very annoying if you have several React application using Webpack Dev Server WS.![]()
I can perform additional tests if you want.
@sylvainDNS Can you please post your traefik configuration. I am trying to get Create React App work with Traefik and getting into same issue. Thanks for your help.
@raix did you ever find the correct fix? It'd be good to have an authoritative answer.
I used react-app-rewired to export devServer config and overwrite webSocketURL to 'auto://0.0.0.0:0/ws' to use browser protocol, hostname and port as described here: https://webpack.js.org/configuration/dev-server/#websocketurl and here https://github.com/timarney/react-app-rewired#extended-configuration-options.
I'm quite a newbie and I don't really know that much about how react works with babel and webpack and everything. I was following a docker course on Udemy by Stephen Grider and I decided to try doing something similar to the course material, but with my own customizations. Anyway - I discovered that when I used a different version of the axios library, the 2 fixes: WDS_SOCKET_PORT=0 and nginx default.conf: location /ws { proxy_pass http://client; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } did not work. However when I used the version of axios from the course, it did.
package.json (2 fixes do not work) "dependencies": { "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", "axios": "^0.27.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" },
package.json (2 fixes do work) "dependencies": { "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4", "axios": "0.18.0" },
Basically what had happened was that I had installed axios independently (running the command npm install axios) in the first case - which caused it not to work. When I re-created the project from scratch and did not run npm install axios in the react folder, but added the dependency "axios": "0.18.0" in the package.json file it worked fine (with the WDS_SOCKET_PORT=0 as well as nginx default.conf location /ws fixes).
I couldn't manage to fix the first case - even by running npm uninstall axios or changing the package.json file to "axios": "0.18.0". I think this is because installing axios independently may have changed other random packages too (because when I do a diff of the package-lock.json files (in the case that worked and the case that didn't), there are some differences in "node_modules/@babel/code-frame": and other @babel things. I don't really understand this - I assume it is because a different version of axios requires different other dependencies, which mean that the fixes don't work. Basically - the message is, it might be a node_modules or dependencies issue and getting the correct set of dependencies may be key. Hope this helps someone.
I was facing the same issue, but with
WDS_SOCKET_PORT=0
it worked for me. No web socket error in the console anymore and hot reload also working. My default.conf currently looks like this:upstream frontend { server client:3000; } upstream backend { server api:5000; } server { listen 80; location / { proxy_pass http://frontend; } location /ws { proxy_pass http://frontend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /api { rewrite /api/(.*) /$1 break; proxy_pass http://backend; } }
My docker-compose file looks like this:
version: '3' services: client: build: dockerfile: Dockerfile.dev context: ./client volumes: - /app/node_modules - ./client:/app environment: # Fixes bug where websocket connection is fixed to default port 3000 - WDS_SOCKET_PORT=0 ... other services
On which system are you running the project? I don't have hot reload on windows 10. On macOS everything works with the same config.
Thanks, it worked for me.