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
- Create a new app.
- Set
HOSTin.env. - Set
proxyinpackage.json. - Run
react-scripts startor 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
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.
@BalzGuenat I can replicate the issue - did this work in webpack 4 (what version?)
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.
- Delete "proxy": "http://localhost:xxxx" in package.json
- run
npm install http-proxy-middleware - 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,
})
);
};
- run
npm start
@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 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,allowedHostsis set to[undefined]becauseprepareUrlsdoesn't setlanUrlForConfigif 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.
@marr
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.
It is actually important to notice this because this misleading snippet is the one from the documentation.
I made a PR to fix the documentation #12049 and change the example snippet to one that works as intended with v5.0.0.
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.
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: @.***>
HOST=<something> DANGEROUSLY_DISABLE_HOST_CHECK=true yarn start
I encountered this issue in a project running docker-compose. Testing this^ solution, in docker-compose, produces below results:
DANGEROUSLY_DISABLE_HOST_CHECK |
HOST |
Startup result | Proxying works? |
|---|---|---|---|
| undefined | undefined | Fails with error 1 below | n/a |
true |
undefined | Starts fine. No warnings. | No - still troubleshooting |
true |
something |
Fails with error 2 below | n/a |
true |
localhost |
Starts with warning 1 below, but React server never returns anything to the browser | n/a |
| undefined | localhost |
Warning 1, then Error 1 | n/a |
| undefined | something |
Warning 1, then Error 1 | n/a |
I suspect my proxying implementation may be bugged, but it's hard to confirm right now.
Error 1
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 2
Error: getaddrinfo ENOTFOUND something
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:83:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'something'
}
Warning 1
Attempting to bind to HOST environment variable: localhost
If this was unintentional, check that you haven't mistakenly set it in your shell.
Learn more here: https://cra.link/advanced-config
https://github.com/facebook/create-react-app/issues/11762#issuecomment-1001295074
This works in a js project, but for some reason not in a ts project (created with npx create-react-app client --template typescript).
Fortunately creating setupProxy.js, even in a typescript project, will still work (as long as the project allows js)
I'd same problem but it fixed by setupProxy.js
The stepProxy.js doesn't work for me. reproduce: https://github.com/bradtraversy/mern-tutorial/tree/main/frontend
The stepProxy.js doesn't work for me. reproduce: https://github.com/bradtraversy/mern-tutorial/tree/main/frontend
This project has no setupProxy.js at all and appears to follow none of the steps described
If you have access to server, just install cors from npm. For Express: https://expressjs.com/en/resources/middleware/cors.html
I have the same problems. For a while it worked with DANGEROUSLY_DISABLE_HOST_CHECK=true but I think an update of express or node (don't remember from which to which version) broke it again.
After spending a couple of hours on it, I settled for a solution with using caddy as a reverse proxy. For anybody looking for a similar solution, here is the snippet from my Caddyfile:
http://localhost:3001 {
# API Backend is running on port 6000
reverse_proxy /api/* http://localhost:6000
reverse_proxy /auth/* http://localhost:6000
# ... add more API end points if necessary
reverse_proxy /* http://localhost:3000
}
Then, run npm with
WDS_SOCKET_PORT=3001 npm start
setting also the WS port to make hot reloading work. Then, you can work on localhost:3001.
So far, it seems to work.
https://stackoverflow.com/questions/70374005/invalid-options-object-dev-server-has-been-initialized-using-an-options-object/72100528#72100528
This is actually likely caused by the address module if thats a dependency here
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
thank you very much for this.
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.
- Delete "proxy": "http://localhost:xxxx" in package.json
- run
npm install http-proxy-middleware- 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, }) ); };
- run
npm start
this helps with my issue