Dave
Dave

Reputation: 19090

How can I configure my prod env vars when I run my build process?

I'm building a React 16.13.0 application. I want to configure an endpoint differently, per environment, so I have set this up in a component, src/containers/FormContainer.jsx, ...

class FormContainer extends Component {
  static DEFAULT_COUNTRY = 484
  static REACT_APP_PROXY = process.env.REACT_APP_PROXY
    ...

I want to build my project for production locally. However locally I have defined this variable

localhost:client davea$ echo $REACT_APP_PROXY
http://localhost:9090

and after I run "npm run-script build," I notice this compiled into my build files ...

(function(e){return e.json()})).then((function(t){console.log(t),n=t.map((function(e){return e})),e.setState({provinces:n})}))}}]),t}(n.Component);S.DEFAULT_COUNTRY=484,S.REACT_APP_PROXY="http://localhost:9090"

Is there any way to not get React to auto-resolve the env var and instead grab it from the production environment? Maybe I need to adjust my build script? Below is what's defined in my package.json file ...

localhost:client davea$ cat package.json 
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.4.0",
    "@testing-library/user-event": "^7.2.1",
    "bootstrap": "^4.4.1",
    "jquery": "^1.9.1",
    "react": "^16.12.0",
    "react-bootstrap": "^1.0.0-beta.17",
    "react-dom": "^16.12.0",
    "react-native-flash-message": "^0.1.15",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.3.1",
    "typescript": "^3.8.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "proxy": "http://localhost:8000",
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Upvotes: 6

Views: 26726

Answers (5)

GMKHussain
GMKHussain

Reputation: 4661

install 'env-cmd' package

npm install --save-dev env-cmd

Update package.json

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "deploy": "gh-pages -d build",
    "start:local": "env-cmd -f .env.local react-scripts start",
    "build:local": "env-cmd -f .env.local react-scripts build"
    "start:stage": "env-cmd -f .env.stage react-scripts start",
    "build:stage": "env-cmd -f .env.stage react-scripts build"
    "start:live": "env-cmd -f .env.live react-scripts start",
    "build:live": "env-cmd -f .env.live react-scripts build"
  },

Run start or build as you want environment by

 // Local environment
 npm run start:local
 npm run build:local
 
 // Stage environment
 npm run start:local
 npm run build:local
 
 // Live environment
 npm run start:live
 npm run build:live

Upvotes: 0

Lourival
Lourival

Reputation: 11

try

yarn build --mode your_env

Upvotes: 1

Garrett
Garrett

Reputation: 1792

For anyone else having this problem, but unsuccessful with the accepted answer try this.

  1. Install env-cmd
  2. In your package.json, set the env in your build command like so: "build:staging": "env-cmd -f .env.<ENV_NAME> react-scripts build",

Note, make sure a file called .env.<ENV_NAME> exists in the root of your project

Upvotes: 2

Mohammad Oftadeh
Mohammad Oftadeh

Reputation: 1449

The following steps may help. Try it:

You can also refer to the original documents for more information:

Adding Custom Environment Variables

First Step:

Create .env file in the root of project

Project structure after making the .env file:

...
- build
- public
- src
    |----- App.js
    |----- index.js
- package.json
- .env
...

Inside of .env file:(for example) Prefix REACT_APP_ is required!

REACT_APP_URL_DEVELOPMENT=http://localhost:8000/api
REACT_APP_URL_PRODUCTION=https://productionDomain.com/api/

Second Step:

package.json file:

Scripts No need to change in package.json file:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "homepage": "http://myWebsite.com",
  "dependencies": {
    ...
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Third Step:

Finally, you can conditionally use the variables you created.

Example:

class Posts extends Component{
    ...

    componentDidMount(){

      // Finally, you can conditionally use the variables you created.
      const url = process.env.NODE_ENV === "development" ? process.env.REACT_APP_URL_DEVELOPMENT : process.env.REACT_APP_URL_PRODUCTION;

      axios.get(url)
        .then(res => { ... })
        .catch(err => { ... });

    }

    render(){
      return(
        ...
      )
    }
}

Faqs section:

process.env is a global Object provided by your environment through NodeJs. Because we don't have NodeJS in browser. But you can access to NODE_ENV by init your app using create-react-app with webpack included by default and perform the above steps. More details below:

There is a built-in environment variable called NODE_ENV. You can access it from process.env.NODE_ENV. This variable changes based on what mode you are currently in. When you run npm start, it is equal to development, when you run npm test it is equal to test, and when you run npm run build it is equal to production. This variable is special as it can be used to access different environment configurations based on your mode.

Upvotes: 6

Shubham Khatri
Shubham Khatri

Reputation: 281616

You are using react-scripts to build your App. You can define environment variables in your .env files.

For variables that are common across your node environment, you can define them in .env file

For variable that are specific to development and production, you can define them in .env.development and .env.production files

Also please prefix your variables with REACT_APP

Once you do that you can add scripts in your package.json to specify a build for a particular NODE_ENV

"scripts": {
    "start": "react-scripts start",
    "build": "NODE_ENV=development react-scripts build",
    "build:prod": "NODE_ENV=production react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

and then you can build your APP for production locally like

yarn run build:prod

and it will use the production environment variables

Read more about it on create react app documentation

Upvotes: 8

Related Questions