Jonnyishman
Jonnyishman

Reputation: 365

React hot reloading breaks when introducing middleware proxy for websocket

Good day, I have a react app using both socket.io-client and http-proxy-middleware. When introducing a proxy for the socket.io websocket the hot reloading feature given by react-scripts start no longer works.

I can see that a WS network call to /sockjs-node is being proxied to the backend service providing the websocket rather than to the react app's development build server. I have attempted to change the websocket path but to no avail. Is there a way to make these two tools place nice?

setupProxy.js file

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(
        '^/api',
        createProxyMiddleware({
            target: 'http://localhost:8012',
            changeOrigin: true,
            pathRewrite:  {'^/api': ''}
        })
    );
    app.use(
        '^/socket.io',
        createProxyMiddleware({
            target: 'ws://localhost:8012',
            changeOrigin: true,
            ws: true,
        })
    );
};

socket.io instance

import io from 'socket.io-client';

const socket = io();

package.json file

{
  "name": "client-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@ant-design/icons": "^4.2.2",
    "@types/node": "^12.12.36",
    "@types/react": "^16.9.34",
    "@types/react-dom": "^16.9.6",
    "@types/styled-components": "^4.4.2",
    "antd": "^4.3.4",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-lazylog": "^4.5.3",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.1",
    "socket.io-client": "^2.3.1",
    "styled-components": "^5.1.0",
    "typescript": "^3.7.5"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "@types/jest": "^24.9.1",
    "http-proxy-middleware": "^1.0.5",
    "jest-fetch-mock": "^3.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Thank you in advance.

Upvotes: 2

Views: 2075

Answers (1)

James
James

Reputation: 130

http-proxy-middleware supports path filtering and using ignores (https://github.com/chimurai/http-proxy-middleware/issues/31).

You can remove the sockjs-node path from your proxy by passing ['!/sockjs-node'] into createProxyMiddleware. Now the live reload path will be skipped.

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(
        '/api',
        createProxyMiddleware(['!/sockjs-node'], {
            target: 'http://localhost:5000/',
            changeOrigin: true,
            ws: true,
        })
    );
};

Upvotes: 5

Related Questions