5

I am new to React and I am going to deploy a React project. The React project is created by create-react-app, then the production code is built by "npm build" and it is host by Express.

In the project, there are some fetch call to a API server, which the URL is want to be configurable. In development, I am able to do this by setting it in the environment variables in the file .env (e.g., REACT_APP_API_URL=http://somewhere/) and imported in the codes.

However, seems those environment variables becomes static after running "npm build", I am not able to change it anymore, even by doing something like "REACT_APP_API_URL=http://otherserver/ node express_server.js" when I start the server.

I would like to ask if there is any way to source some configurations for the codes after "npm build", it is the best if it can be source from a file or .env, from environment variables is ok for me too.

Thank you.

wing999
  • 327
  • 2
  • 10

2 Answers2

3

The environment variables gets embedded in the files in the build step, so you need to assign the proper values to them when you call react-scripts build.

Example

"scripts": {
  "start": "cross-env REACT_APP_API_URL=http://somewhere/ react-scripts start",
  "build": "cross-env REACT_APP_API_URL=http://otherserver/ react-scripts build",
}
Tholle
  • 108,070
  • 19
  • 198
  • 189
  • Thank you for quick response, so, seems that there is no way to import or change configurations after `react-scripts build` is done? – wing999 Jul 18 '18 at 12:17
  • @wing999 Sadly not. You could have your server inject environment variables into the HTML file, and then have the JavaScript bundle read these global variables when it is loaded in the browser, but there is no way to change the actual JavaScript file dynamically like that. – Tholle Jul 18 '18 at 12:19
  • 1
    Seems that I need to find other workaround. May be setting up a proxy in the Express to make the URL of the API server configurable. – wing999 Jul 18 '18 at 13:11
  • @wing999 What is you use case? You don't have the option to run the build script once for every different domain you have? – Tholle Jul 18 '18 at 13:14
  • That is one of the option indeed, but I just want to see if it is possible to avoid to re-build everything. May be because i am a old-mind-set programmer, thinking that the risk of changing some configuration is less than rebuilding things. – wing999 Jul 19 '18 at 02:41
0

I found a way of fetching a custom conf.json file from a backend and apply the parameters in react as follows in index.tsx file of my react app:

const CURR_ENV = process.env.REACT_APP_ENV;

console.log('ENV: ' + CURR_ENV)

if (CURR_ENV === 'prod') {
    console.log("fetching conf.json ...")
    fetch('conf.json')
        .then(response => response.json())
        .then(data => {
            console.log("data=" + JSON.stringify(data))
            const amplify = data['amplify'];
            console.log("amplify=" + JSON.stringify(amplify))
            Auth.configure(amplify);
            Auth.configure(amplify);

            const backendUrl = data['backendUrl'];
            console.log("backendUrl=" + JSON.stringify(backendUrl))
            localStorage.setItem('backend_url', backendUrl);
            console.log("successfully configured amplify and apigw")
        })
        .catch(error => console.error(JSON.stringify(error)))
}
else {
    localStorage.setItem('backend_url', process.env.REACT_APP_BACKEND_URL?process.env.REACT_APP_BACKEND_URL:"");
    Amplify.configure(awsmobile);
    Auth.configure(awsmobile);
}

ReactDOM.render(
  <Router>
      <div>
          <Route path="/" component={App}/>
      </div>
  </Router>,
  document.getElementById('root')
);
Romande
  • 561
  • 2
  • 4
  • 16