Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set proxy in package.json to env variable

Tags:

node.js

npm

I need to set the proxy value in my package.json at runtime, like with an environment variable. How could this be done?

// package.json
{
  "name": "demo",
  "proxy": process.env.MY_PROXY_VAL , // <- how?
  "dependencies": {},
  "scripts": {},
}

Thanks.

like image 520
Scott Avatar asked Sep 22 '16 21:09

Scott


People also ask

Can package json access environment variables?

Can package json use environment variables? By using dotenv and cross-var together, we're able to read in whichever . env files we want, or consume existing environment variables (from cli, bash_profile, CI, etc) and then easily substitute them into our package. json scripts and it works across development platforms!

Where do I put proxy in package json React?

To configure the proxy, you'll need to add the following line to your package. json . Then, in your React app, you can make API requests by using relative paths. For example, http://localhost:8000/api/todos becomes /api/todos .

What is proxy field in package json?

proxy field in package. json is used to proxy all requests from frontend domain to backend. For example, you have: Backend (REST API): localhost:5000/api/user/:id.


2 Answers

So I am converting my comment into an answer, since I think it is important to point out an actual solution to this problem.

I was searching for that exact same answer, and also tried setting the HTTP_PROXY and HTTPS_PROXY variables via an .env file, and also directly from within a script. However this does not solve the problem since this will overwrite the system proxy settings for the local machine, which I don't think was something the OP intended to do. The result can be that you cannot load npm packages anymore, because of incorrect system proxy settings.

Instead, there is a way of manually configuring the proxy for a CRA in development, as pointed out by the official docs: https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually

With this you should create a local setupProxy.js file under the /src folder of the project, which will then override the proxy set in package.json. Of course then you have to make sure that all the paths are correctly set, but it works well and you have fine grained control over which pages in your app will be proxied and which will not.

To target specifically your question about how to set the proxy via an environment variable, here is an example how you could do it with the setupProxy approach and the createProxyMiddleware:

// Sample of how to setup a proxy middleware with environment variables

//// file: <project_root>/src/setupProxy.js

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

module.exports = function(app) {
  app.use(
    '/rest',
    createProxyMiddleware({
      target: process.env.REACT_APP_PROXY_HOST,
      changeOrigin: true,
    })
  );
};


//// file: <project_root>/.env

REACT_APP_PROXY_HOST=https://localhost:6700

In this case I only wanted to proxy requests targeted to the /rest endpoint, for which I created a new endpoint. All other requests will still go to the default localhost:3000 Url, serving the react app.

The host is defined via the environment variable REACT_APP_PROXY_HOST. I defined the variable in the local .env file, but you could also directly set it inside a script in package.json if needed.

Update: Even though the original question was already solved for me, I had an additional issue trying to forward requests to a server running on https. The previous development setup has been fine with the static proxy set in package.json. However when using the createProxyMiddleware and targeting a server running on https with certificates, the path to the used certificate has to be provided.

// Sample of how to setup a proxy middleware with environment variables 
// targeting a server running on https

//// file: <project_root>/src/setupProxy.js

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

const protocol = JSON.parse(process.env.HTTPS) ? "https:" : "http:";
const host = process.env.REACT_APP_PROXY_HOST
const port = process.env.REACT_APP_PROXY_PORT

module.exports = function(app) {
  app.use(
    '/rest',
    createProxyMiddleware({
      target: {
        protocol: protocol,
        host: host,
        port: port,
        pfx: fs.readFileSync('src/root-cert.pem')
      },
      changeOrigin: true,
    })
  );
};


//// file: <project_root>/.env

HTTPS=true
REACT_APP_PROXY_HOST=localhost
REACT_APP_PROXY_PORT=6700

In this case instead of providing the target as a string, it should be given as an object containing protocol, host, port and an attribute pfx, which contains the certificate to validate the server via https. In this case it is a hardcoded path within the project source directory, however it could also be set using environment variables.

The setting HTTPS=true overwrites the default development setup and will by default start the development server at https://localhost:3000. With this setting as well as providing the correct certificate the server running on https can be reached without issues.

For reference, this solution is officially linked in the documentation of http-proxy-middleware and the underlying node-http-proxy:

  • https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/https.md
  • https://github.com/http-party/node-http-proxy#http---https-using-a-pkcs12-client-certificate

This question also got some attention at other places, e.g.

  • https://github.com/facebook/create-react-app/issues/3783
  • https://github.com/facebook/create-react-app/issues/4288
  • https://github.com/usc-isi-i2/kgtk-browser/issues/32

Hope to help someone searching for the same problem, if there are any updates to this or things change feel free to add suggestions in the comments.

like image 94
aegger Avatar answered Sep 17 '22 09:09

aegger


It will automatically read from HTTPS_PROXY or HTTP_PROXY so you dont need to do that.

From the docs:

A proxy to use for outgoing https requests. If the HTTPS_PROXY or https_proxy or HTTP_PROXY or http_proxy environment variables are set, proxy settings will be honored by the underlying request library.

like image 43
Nix Avatar answered Sep 18 '22 09:09

Nix