React Application External Configuration with Webpack

React is one of the best and most used libraries to build user interface. It does the job, has sufficient documentation and good dev community. But when using only pure React, there are some problems with properly sharing/deploying an app. It is just not enough. That’s where the help of Webpack, a popular module bundler, comes in.  Below we will discuss how to use some extensions based on the Webpack, such as react-app-rewired.

Let’s imagine this scenario:  a developer creates a Web React application. It fulfills the business requirements, works locally and is deployed and tested on some kind of dev or staging environment. The natural flow of such an app is to be deployed on production (live) server as well.

How do we do it?  We change a few configuration settings in the application code, rebuild and deploy via Jenkins script for example. But there are a few hidden problems here. The code is already built for stage, can’t we skip the second one? It is not a big deal to rebuild a small app, but for bigger products the process could be time- consuming and not necessary with better configuration. Another potential issue is that our configuration will be merged and exposed in the compiled bundle.js file. The server settings, public product keys for any external service and so on are visible; not the behaviour we would always want.

How could this danger be averted? A simple and effective solution is to have external config file. It will solve several problems at once:

  • Better maintainability. The program could be deployed on different environments with some small changes in the external config. The main application code will remain intact.
  • No extra rebuilds.
  • Security. Тhe keys could be received from another server and not exposed here.

Let’s demonstrate how to do such а configuration from scratch.

1. We will use a very basic React application in the demo for the sake of simplicity. The easiest way to create such “Hello world” example is to use create-react-app command
 
npx create-react-app react-app-external-config

More info about create-react-app

Unfortunately, React has no internal way to easily manage these web configurations. This is why we use Webpack – to exploit the power of create-react-app but without the limits of no configuration. It is not the best practise to eject, manually, change the Webpack configs and rebuild too. There are other packages to fix it though such as react-app-rewired.

2. Go to the new react-app-external-config folder and add react-app-rewired there.  This package gives the option to customise the Create React App WITHOUT ejecting.
 
npm i -D react-app-rewired

More info about react-app-rewired

3. Let’s create our externalConfig.js file in the public directory. Here it contains a simple {key,value} pair which will be used later
 

./public/externalConfig.js:

const externalConfig = {
   exampleKey: "key_for_development_environment",
}
4. Include the new script in the script section of index.html file’s body

In this way, the script won’t be added to the compiled .js file with all the code of our app. It is better due to the security concerns discussed above and the ease of maintainability. The content could be easily changed without any need to rebuild the whole application.

5. Create the webpack config mapper file in the root folder:

Note: according to the react-app-rewired documentation, the name is fixed to config-override.js:

module.exports = function override(config, env) {
    if (!config.externals) {
        config.externals = {};
    }

    config.externals = {
        ...config.externals,
      externalConfig: 'externalConfig',
    };

    return config;
};

Here we override the webpack external settings to exclude the new config dependency. Originally, such webpack.config.js file looks like:

module.exports = {
  //...
  externals: {
    mappingNameToLibrary: 'jQuery'
  }
};

This leaves any dependent modules unchanged and the module could still be used with: import $ from 'mappingNameToLibrary';

More info about webpack and webpack externals

6. Edit the build and run settings in package.json. We will use react-app-rewired instead of react-scripts
"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

should become:

"scripts": {
    "start": "react-app-rewired start --scripts-version react-scripts",
    "build": "react-app-rewired build --scripts-version react-scripts",
    "test": "react-app-rewired test --env=jsdom --scripts-version react-scripts",
    "eject": "react-scripts eject"
  }

Note: Don’t edit the eject script! It’s called only once a project and you have full control over the webpack configuration after that and react-app-rewired is not required anymore.

7. Check the result:
npm start

The default React start page is loaded. Let’s edit a bit ./src/App.js to show the result:

import externalConfig from 'externalConfig'
...

This is your external configuration key:

{externalConfig.exampleKey}

The object KEY could be imported anywhere in the project now and KEY.key will access it’s value

The result should be:

8. (optional) Change the value of exampleKey in ./public/externalConfig.js:

exampleKey: "production_key",

Conclusion:

The code could be deployed with the new settings. externalConfig.js could be modified manually by bash script or any other automatic way. The benefits from external config solution apply to containers as well. The updated file could be mounted as volume without changes to the container.

The full code can be found here in GitLab.

 

Share

Share on facebook
Share on google
Share on twitter
Share on linkedin
Share on pinterest
Share on print
Share on email