Managing a variable configuration for a Flux application with gulp

Once you're done with the development of your Flux application, it is time to deploy it to your staging and/or production environment. But what if the app relies on configuration values that need to be specific to these environments? We will see how to address such a concern with Gulp.

We are going to store our configuration in JSON files. Values will be defined as environment variables, which can be set upon packaging your app with a continuous integration tool, and will be applied by a good ol' Bash script with regard to default values used for development. I assume all files, including gulpfile.js, are located at the project's root. We will begin by writing a sample configuration file, named (for example) config.json.dist:

{
"myParam1": "this value is environment-agnostic",
"myParam2": "?MY_PARAM_2?"
}

Next, we need to copy this file to config.json, which we will then require in our JavaScript code (with the help of Browserify). This is where gulp comes into play:

var gulp = require('gulp'),
rename = require('gulp-rename');

gulp.task('config', function() {
gulp.src('config.json.dist')
.pipe(rename('config.json'))
.pipe(gulp.dest('.'));
});

Make sure to npm install gulp-rename --save-dev if necessary.

We then want the ?MY_PARAM_2? placeholder to be swapped for the actual value. Let's set up the envify script that does that:

#!/bin/bash

set -e
cd "`dirname "$0"`"

declare -A DEFAULTS

# Set up default configuration values
DEFAULTS["MY_PARAM_2"]="this one isn't"

# Push them as environment variables if they don't already exist
for key in "${!DEFAULTS[@]}"; do
if [ -z "${!key}" ]; then
declare -x "$key"="${DEFAULTS[$key]}"
fi
done

# Edit configuration files accordingly
sed -i "s,?MY_PARAM_2?,$MY_PARAM_2,g" config.json

Have gulp run this script after copying the sample file:

gulp.task('envify', ['config'], function() {
gulp.src('')
.pipe(tasks.shell(['chmod +x envify', 'envify']));
});

Note: the ['config'] thing should make gulp run the config task prior to this one; however, I sometimes have encountered race conditions forcing me to make the shell sleep before actually running the script. It's a dirty hack though, so if you have had the same issue and found a better way to work around it, I'm interested!

After running gulp envify, you should see a config.json file with the following contents:

{
"myParam1": "this value is environment-agnostic",
"myParam2": "this one isn't"
}

If you do it again after running export MY_PARAM_2="I love bananas", the file will look like this instead:

{
"myParam1": "this value is environment-agnostic",
"myParam2": "I love bananas"
}

You can thus do the same in your CI job, and that's how you get environment-specific configuration in a Flux application. Stay tuned!

I would like to seize this opportunity to say that all my affection goes to victims of terrorism, from Paris last friday to other places in the world where such atrocities happen frequently, such as Beirut. Remember freedom and love cannot be killed; stay strong together and support each other in the hope of brighter days.