Is it possible to set proxy settings in CRA differently than with package.json? For example using ENV variables?
From CRA docs it states
Use environment variables to inject the right server host and port into your app.
Is this sentence about proxy or dev server itself?
According to the this and this, the only way to influence proxy settings is via package.json.
To change the default port for a create-react-app project, update the start command in your package. json file to specify the port, e.g. "PORT=3456 react-scripts start" on macOS and Linux and "set PORT=3456 && react-scripts start" on Windows.
Proxy Setup with Create-React-App All you have to do is add a proxy field to your package. json file, like shown below. "proxy": "http://localhost:3000", This line instructs the development server to proxy any unknown requests to your API server in development mode.
Note: this feature is available with [email protected] and higher.
You can manually configure proxy now. You need to install http-proxy-middleware
first.
npm install http-proxy-middleware --save
Then create a file src/setupProxy.js
with following content.
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api', // You can pass in an array too eg. ['/api', '/another/path']
createProxyMiddleware({
target: process.env.REACT_APP_PROXY_HOST,
changeOrigin: true,
})
);
};
You can add proxy now in the .env
file, remember you need the REACT_APP_
prefix for development server to pick up the environment variable.
REACT_APP_PROXY_HOST=http://localhost:5000
Ref: Proxy manually
Use environment variables to inject the right server host and port into your app.
This refers to neither the proxy server nor the dev server. This is a recommendation on how to handle per-environment server settings if proxy
does not provide enough flexibility for you (i.e. if you need to use protocols other than http
, https
, or ws
). For example, if you have an api call within your code, you can use an environment variable to do something like this:
axios(process.env.REACT_APP_BASE_URL + endpoint, options).then(data=>{ console.dir(data); })
Where each environment has it's own definition of REACT_APP_BASE_URL
.
package.json
:It is not possible to influence proxy settings without modifying package.json
.
See Configuring the Proxy Manually (CRA docs)
package.json
is the only documented way to influence proxy settings.
You can also see line 96 of CRA's start.js
. This implementation leaves absolutely no ability to use ENV vars to inject the host/port to CRA's proxy settings.
This is really one of the reasons I detest CRA, to be honest. All of this behavior is so very easily handled when not bound by the limitations of CRA.
npm run eject
All of these problems will go away instantly... The start.js
script referenced above is a bit of the code that is ejected. So you would very easily be able to replace those proxy settings with ENV vars.
Just be certain to create a checkpoint for yourself prior to doing this as there is no reverting an ejection.
However--if you must stick with CRA--you CAN very easily modify package.json
using environment variables.
package.json
at build time:This is essentially what CRA does with the REACT_APP_
env vars (though it directly injects them into process.env
).
package.json
is just a big JSON object, so all you need to do is parse it on the server side right before you deploy, update the "proxy"
value to the ones provided by your ENV vars, save the file, and then run your build/deploy.
Here is a very simple example of how to achieve this, you just need to run this script before deployment in a context where you still have access to process.env
:
const fs = require('fs');
// read/process package.json
const file = './package.json';
let pkg = JSON.parse(fs.readFileSync(file).toString());
// at this point you should have access to your ENV vars
pkg.proxy = `${process.env.HOST}:${process.env.PORT}`;
// the 2 enables pretty-printing and defines the number of spaces to use
fs.writeFileSync(pkg, JSON.stringify(file, null, 2));
I know this doesn't explicitly answer the question of how to handle this "without package.json", but I don't think that's the necessary approach anyways.
Further, this DOES asnswer the title question of "How to inject port and host using ENV variable in Create React App Proxy settings?"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With