create-react-app: In CRA 5.0.0, `react-scripts start` fails when both `HOST` in `.env` and `proxy` in `package.json` are defined.

Describe the bug

In CRA 5.0.0, react-scripts start fails when both HOST in .env and proxy in package.json are defined.

Did you try recovering your dependencies?

This occurs on a newly created project.

Which terms did you search for in User Guide?

“allowedHosts” and others, came up empty.

Environment

Environment Info:

  current version of create-react-app: 5.0.0
  running from /home/z003w3we/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app

  System:
    OS: Linux 5.4 Ubuntu 20.04.3 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz
  Binaries:
    Node: 16.13.0 - ~/.asdf/installs/nodejs/16.13.0/bin/node
    Yarn: 1.22.10 - ~/.asdf/shims/yarn
    npm: 8.1.3 - ~/.asdf/plugins/nodejs/shims/npm
  Browsers:
    Chrome: 96.0.4664.45
    Firefox: 95.0
  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

  1. Create a new app.
  2. Set HOST in .env.
  3. Set proxy in package.json.
  4. Run react-scripts start or something to that effect.

Expected behavior

App starts.

Actual behavior

I get this error:

> yarn start
yarn run v1.22.10
$ react-scripts start
Attempting to bind to HOST environment variable: test.localhost
If this was unintentional, check that you haven't mistakenly set it in your shell.
Learn more here: https://cra.link/advanced-config

Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
 - options.allowedHosts[0] should be a non-empty string.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Reproducible demo

https://github.com/BalzGuenat/cra-test

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 14
  • Comments: 19 (1 by maintainers)

Commits related to this issue

Most upvoted comments

The answer from josipat in

https://stackoverflow.com/questions/70374005/invalid-options-object-dev-server-has-been-initialized-using-an-options-object/70491173#70491173

works. I will just paste his answer here again, just for easy access.

  1. Delete “proxy”: “http://localhost:xxxx” in package.json
  2. run npm install http-proxy-middleware
  3. Create a file setupProxy.js inside your src folder and write the following codes:
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:6000',
      changeOrigin: true,
    })
  );
};
  1. run npm start

I encountered the problem when I tried:

HOST=<something>  yarn start

(and I have a proxy: setting in package.json).

I debugged a bit and found that in webpackDevServer.config.js#L46, allowedHosts is set to [undefined] because prepareUrls doesn’t set lanUrlForConfig if a host is specified.

By examining the code at that link I discovered the workaround:

HOST=<something>  DANGEROUSLY_DISABLE_HOST_CHECK=true  yarn start

Before you try that you should read the comment following webpackDevServer.config.js#L25 and determine whether that is dangerous for your situation. In my case it’s harmless.

@sunmoon-idegu I’m not sure how important it is, but the syntax of the above snippet is a little misleading. I think what the intention was to create a proxy on the /api routes, rather than the / routes. I noticed this because the output of the log was saying:

[HPM] Proxy created: / -> https://localhost:6000

Instead of:

[HPM] Proxy created: /api -> https://localhost:6000

So, to fix this you will notice the path (HPM’s context) is not being set, therefore defaulting to /. You can correctly set via:

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

module.exports = function(app) {
  app.use(
    createProxyMiddleware('/api', {
      target: 'http://localhost:6000',
      changeOrigin: true,
    })
  );
};

Also, saving someone a doc lookup, you will likely need secure: false if testing locally and receiving SSL errors.

I debugged a bit and found that in webpackDevServer.config.js#L46, allowedHosts is set to [undefined] because prepareUrls doesn’t set lanUrlForConfig if a host is specified.

Yeah, it works in webpack 4.44.2.

The answer from josipat in

https://stackoverflow.com/questions/70374005/invalid-options-object-dev-server-has-been-initialized-using-an-options-object/70491173#70491173

works. I will just paste his answer here again, just for easy access.

1. Delete "proxy": "http://localhost:xxxx" in package.json

2. run `npm install http-proxy-middleware`

3. Create a file setupProxy.js inside your src folder and write the following codes:
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:6000',
      changeOrigin: true,
    })
  );
};
4. run `npm start`

thank you its working properly

I’d same problem but it fixed by setupProxy.js

Glad you found a workaround Brett. Just to clear up why your # issue. Those are client only elements of the URL and do not make it to the server. I forget where I read that but it would explain your observations.

On Wed, Apr 20, 2022 at 8:36 AM Brett Pittman @.***> wrote:

Dropping this here for others who may have a similar issue:

My routes did not include “/api” in the API calls. Instead, they relied on the proxy in package.json being used in the event of 404’s. When using the previously mentioned solution of using http-proxy-middleware, if I set the context to “/”, the proxy was used for all routes, including ones meant for the client. Due to the number of API calls in my app, it would be a significant time commitment to change them all to include the “/api”

I tried using [“/**”,“!/#/”] to exclude hash routes, but for some reason, it looks like the “#/” wasn’t getting looked at at all. The requests were still being proxied, and in the express logs, the route was simply “/” rather than “/#/”. My guess is that the hash and everything after it are not truly considered part of the route.

The solution to all of this ended up being adding the following to my index.js:

import axios from ‘axios’;

axios.defaults.baseURL = ‘/api’;

This prepends “/api” to all axios requests, which allows me to use the solution mentioned by marr.

— Reply to this email directly, view it on GitHub https://github.com/facebook/create-react-app/issues/11762#issuecomment-1103881634, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAK2WEAZDOJQ22BT2N6EQDVF723TANCNFSM5KDPQPNQ . You are receiving this because you were mentioned.Message ID: @.***>