I come from a .Net background and have been writing web applications using ASP.Net MVC since it was released. One of the things I have taken for granted over the years is how easy configuration management is on server-side web applications.
In ASP.Net your
Web.config file contains server-side web application settings. You can create different configuration settings by creating a new build type in the Configuration Manager. By default, there is a debug config
Web.debug.config and release config
Web.release.config. These files are transformation files which allow you to specify which settings you want to override in the
Here is the scenario: each project usually has 4 environments that need to be managed.
Local development - run the web site on your machine in dev mode and run unit tests against the source files Dev - production or dev build deployed to a development environment for automated testing usually after every commit QA - production build deployed to a production-like environment and controlled by our QA department Production - production build deployed to a production environment
There are also 4 different API environments, local, dev, QA, and production. The production build needs to point to one of these three API tiers depending on which environment it is deployed to.
React and Redux Webpack for to prepare the site for distribution npm for package management and tasks ava for unit testing babel for transpiling ES6 and ES7 features
My first thought was to use webpack features to expose a Config external.
To add the QA settings I copied the webpack.prod.config and created a webpack.qa.config. The only difference was the Config external. Here is an example of the production external:
This obviously didn’t work for the same reason as the first attempt. When running tests locally we don’t pack the web site. I did however like this solution more simply because we were able to specify which config we wanted as a parameter in the build. So this did take care of having a duplicate production webpack config for QA.
The final solution was to simply go back to good ole’ copying files.
I created a config folder and put our configuration settings in json files
The trick is to copy one of the environment specific configuration files to a
default.json file like this:
For local development I added a prestart step to copy the
dev.json file before our tests start:
Here is the testSetup.js:
In this case the dev API URL does get copied. In our tests we use sinon to mock the API call so the API doesn’t actually get called. We really just need the require statement not to fail on us.
Now for the dev, QA, and prod builds that use the webpack.prop.config. Our build process calls a build.js file that calls webpack and pipes its output to the console. Before calling webpack I added a copy block that copies the correct config based on arguments passed to it.
I added an environment specific npm build task for dev and QA:
Our CI environment will call the
build:dev task for develop branch commits and build for master branch commits.
And that’s it!