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.
- 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.
- Create an alternate config file in your config directory, called config-prod.js or config-test.js.
- 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.
- Place the following code in your .cordova/hooks/after_prepare directory.
- 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