简体   繁体   中英

Externalize different environment variables for different environments in React

Is there any way to externalize completely environment variables (secret keys included) in a React app in a DevOps context? We want to automate our builds for different environments (each environment has its own environment variables). We have looked into environment variables in React using Webpack, but it doesn't quite satisfy our need and we can't externalize environment variables with this approach. Besides, we would have to explicitly declare all these variables inside webpack config file, which would be bloated if we did this. We think that the best way to go is to put api secrets in Firebase and runtime specifics inside a jenkins script.

We are using Jenkins as our CI/CD server and the app runs is deployed with nginx in a Docker container.

You may create two.env files, .env and.env.prod at the root level and can define your particular 'variables' related to specific environment into these env files. Then in your code you should be able to access them through process.env.NODE_ENV

if(process.env.NODE_ENV === "production"){
    //Execute this in production environment
    var url= `${process.env.REACT_APP_AC_ORIGIN}/`;
    url = url + ...,
}else{
    //Execute this in dev environment
    var url= `${process.env.REACT_APP_AC_ORIGIN}/`;
    url = url + ...,
}

.env

REACT_APP_AC_ORIGIN=https://example1.com

.env.prod

REACT_APP_AC_ORIGIN=https://example2.com

If you have multiple environments, say, production, staging, QA, and so on, you may even consider generating dynamic URLS assuming that different environments will be accessed by different hostnames in the browser, Something like this:

api-config.js

  let backendHost;
const apiVersion = 'v1';

const hostname = window && window.location && window.location.hostname;

if(hostname === 'realsite.com') {
  backendHost = 'https://api.realsite.com';
} else if(hostname === 'staging.realsite.com') {
  backendHost = 'https://staging.api.realsite.com';
} else if(/^qa/.test(hostname)) {
  backendHost = `https://api.${hostname}`;
} else {
  backendHost = process.env.REACT_APP_BACKEND_HOST || 'http://localhost:8080';
}

export const API_ROOT = `${backendHost}/api/${apiVersion}`;

And then you can import it like this:

import { API_ROOT } from './api-config';

function getUsers() {
  return fetch(`${API_ROOT}/users`)
    .then(res => res.json)
    .then(json => json.data.users);
}

OR, you can define your variables at run time on different environments.

$ REACT_APP_API_HOST=example.com yarn run build

# The resulting app would have
#   process.env.REACT_APP_API_HOST === "example.com"
#   process.env.NODE_ENV === "production"

Ref: https://daveceddia.com/multiple-environments-with-react/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM