Search code examples
importconfigurationenvironment-variablescreate-react-app

Import config files based on environment with Create React App


I have files I want to import based on environment. Currently I import it into the file like this

import { myConfig } from "../config/my-config";

however I would like to do it based on environment import the correct config file based on environment.

So ideally I would have (they could be json and not TS)

my-config-dev.ts
my-config-staging.ts
my-config-prod.ts

How can I use the correct import based on the environment?

The easiest way would be use normal env variables in CRA e.g REACT_APP_MY_API_KEY, but I have about 3 of these config files and for maintainability I would like them to be in their own ts or json file.


Solution

  • For more info, see Adding Custom Environment Variables

    From your example, I don't see the reason you should create the config file for each environment. Putting the config as REACT_APP_XX environment variables in the .env file is enough.

    project directory structure:

    ✗ tree -a -L 3 -I 'node_modules|public|.git' 
    .
    ├── .env.development
    ├── .env.production
    ├── .env.staging
    ├── .gitignore
    ├── package-lock.json
    ├── package.json
    └── src
        ├── App.js
        ├── App.test.js
        ├── config
        │   ├── dev.js
        │   ├── index.js
        │   ├── prd.js
        │   └── staging.js
        ├── index.js
        ├── reportWebVitals.js
        └── setupTests.js
    
    2 directories, 15 files
    

    .env.development:

    REACT_APP_ENV=dev
    

    .env.staging:

    REACT_APP_ENV=staging
    

    .env.production:

    REACT_APP_ENV=prd
    

    src/config/dev.js:

    const config = {
      domain: 'http://example-dev.com'
    }
    export default config;
    

    src/config/staging.js:

    const config = {
      domain: 'http://example-staging.com'
    }
    export default config;
    

    src/config/prd.js:

    const config = {
      domain: 'http://example.com'
    }
    export default config;
    

    src/config/index.js:

    import dev from './dev';
    import staging from './staging';
    import prd from './prd';
    
    const config = { dev, staging, prd }[process.env.REACT_APP_ENV]
    
    export { config }
    

    App.js:

    import './App.css';
    import { config } from './config';
    
    function App() {
      return (
        <div className="App">
          <p>NODE_ENV: {process.env.NODE_ENV}</p>
          <p>domain: {config.domain}</p>
        </div>
      );
    }
    
    export default App;
    

    We can Customizing Environment Variables for Arbitrary Build Environments using the env-cmd package.

    npm scripts:

    "scripts": {
      "start": "react-scripts start",
      "build": "react-scripts build",
      "build:staging": "env-cmd -f .env.staging npm run build",
      "build:dev": "env-cmd -f .env.development npm run build",
      "test": "react-scripts test",
      "eject": "react-scripts eject"
    },
    

    Run npm run build:dev, then npx serve -s build:

    enter image description here

    Run npm run build:staging, then npx serve -s build:

    enter image description here

    For production environment build, run npm run build.

    enter image description here