score:-1

You can define env variable for port and host. REACT_APP_PORT: "PORT of Application", REACT_APP_HOST: "host of application"

To inject all the env to your application you can use webpack define plugin.

You need to add in plugins section like.

const env = require("path to your env file")
//other webpack settings
plugins: {
//plugins
new webpack.DefinePlugin(env)
}

Now if you see the code of create-react-app it looks in env variable first to find the port and host.

Also, note that

You MUST create custom environment variables beginning with REACT_APP_. Any other variables except NODE_ENV will be ignored to avoid accidentally exposing a private key on the machine that could have the same name

score:2

Is it possible to set proxy settings in CRA differently than with package.json?

No. It is not possible. Well, at least not yet (2017/01/14).

The React proxy functionality is getting a bit complicated and as a result, the idea of setting up a proxy in a React app from env variables will be implemented as soon the simplification of the "advanced" proxy configuration is finished.

Is this sentence about proxy or dev server itself?

It Is about the dev server itself. All proxy configuration, as things stand, is configured in package file.

score:10

Regarding:

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.


Without 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.


You could just eject create react app:

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.


How to inject ENV vars into 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?"

score:10

Note: this feature is available with react-scripts@2.0.0 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


Related Query

More Query from same tag