Build Configurations in Cordova using Hooks

When working with Cordova or Phone Gap, you might need a way to configure your dev build differently from your production build. For example, you might have a set of web services to be used for development, and another for production. This simple Cordova Hook loads the configuration appropriate to the build.

Hooks are a well documented mechanism in Cordova which executes the developer’s custom scripts at certain points in the build process. The best example I have found is this post by Dan Moore.

In this example, all settings for a given configuration are in one file. The appropriate files is substituted in when you build (or “prepare”) your project. This is written in node.js for portability.

  1. Wire up your code so that all “switchable” settings are in one file, config.js. Here’s an example:
    var config = {
        oneSvc: "http://www.example.com/ws/MyService.svc/MyService",
        anotherSvc: "http://www.example.com/ws/YourService.svc/YourService"
    }
    

    …then use config.oneSvc and config.anotherSvc to access the settings in your code. Remember to include config.js in your index.html.

  2. Create an alternate config file in your config directory, called config-prod.js or config-test.js.
  3. In your development environment, set a variable called TARGET with the appropriate value (e.g. “prod” or “test”). If this variable is not set, config.js will be used as-is.
  4. Place the following code in your .cordova/hooks/after_prepare directory.
  5. Build the project as usual.
#!/usr/bin/env node
/**
 * Created by Michael on 5/13/2014.
 *
 * Detect the current build by looking at the TARGET env variable.
 * If TARGET does not exist, make no change.
 * Otherwise, replace config.js with config/config-xxxx.js (where TARGET=xxxx)
 * If config-xxxx.js doesn't exist, execution will fail.
 *
 * Before running this, set the target as:
 *    export TARGET=prod
 *
 */
var fs = require("fs");
var path = require("path");
var rootdir = process.argv[2];
console.log("Running hook: "+path.basename(process.env.CORDOVA_HOOK));

if (process.env.TARGET) {
    var srcfile = path.join(rootdir, "config", "config-"+process.env.TARGET+".js");

    //do this for each platform
    var configFilesToReplace = {
        "android" : "platforms/android/assets/www/js/config.js"
        ," ios" : "platforms/ios/www/js/config.js"
    };

    for(var platform in configFilesToReplace) {
        console.log("Modifying config for platform "+platform+", TARGET="+process.env.TARGET);
        var destfile = path.join(rootdir, configFilesToReplace[platform]);

        if (!fs.existsSync(srcfile)) {
            throw "Missing config file: "+srcfile;
        } else {
            console.log("copying "+srcfile+" to "+destfile);
            fs.createReadStream(srcfile).pipe(fs.createWriteStream(destfile));
        }
    }
} else {
    console.log("TARGET environment variable is not set.  Using default values.");
}

6 comments

  1. Pingback: How to integrate two or more google-services.json file in one project using ionic v3 - ErrorsFixing

Leave a Reply to Michael Cancel reply

Your email address will not be published. Required fields are marked *