Apache Cordova : use different settings in config.xml for debug and release

If you use different environments that are defined in command line, you could create a template config.xml (the file is config.tpl.xml) and a before_prepare cordova hook to replace the variables in the template with the correct values and save the generated content in config.xml.

The hook is:

#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var compile = require('es6-template-strings/compile');
var resolveToString = require('es6-template-strings/resolve-to-string');

var ROOT_DIR = process.argv[2];
var FILES = {
    SRC: "config.tpl.xml",
    DEST: "config.xml"
};

var env = process.env.NODE_ENV || 'dev';
var envFile = 'src/environments/environment.' + env + '.json';

var srcFileFull = path.join(ROOT_DIR, FILES.SRC);
var destFileFull = path.join(ROOT_DIR, FILES.DEST);
var configFileFull = path.join(ROOT_DIR, envFile);

var templateData = fs.readFileSync(srcFileFull, 'utf8');

var configData = fs.readFileSync(configFileFull, 'utf8');
var config = JSON.parse(configData);

var compiled = compile(templateData);
var content = resolveToString(compiled, config);

fs.writeFileSync(destFileFull, content);

I use the environment variable as NODE_ENV here, if you use another (like APP_ENV) just do the corresponding changes in the hook above. The hook loads a json from src/environments/environment.[env].json, like environment.dev.json or environment.prod.json (it can be changed in the hook above).

In config.tpl.xml:

<content src="${CONTENT_URL}" />

It would turn into ${CONTENT_URL} into the correct url, based on the environment file used (you need to have a property CONTENT_URL in the environment json files).

For more info, see https://stackoverflow.com/a/46345926/4850646


UPDATE: Ok this IS working for me. I just needed to update the paths to load common.xml and write config.xml.

I am toying around with using one of the hooks, probably the before_prepare and before_run. I need to test it out but this could suffice

I placed my config.xml into a subfolder I created so it doesn't get overwritten, or you can just rename it. And then I use xml2js to load, parse, and also rebuild back to xml.

#!/usr/bin/env node
const xml2js = require('xml2js');
const fs = require('fs');

const parseString = xml2js.parseString;
const builder = new xml2js.Builder();

const stagingDeploymentKey = "YOU_STAGING_KEY";
const productionDeploymentKey = "YOU_PROD_KEY";

/************************************************************
 * load our commong config xml and parse it into a JS object
 */
var commonXML = fs.readFileSync(__dirname + '/../configs/common.xml').toString();
var commonObj;
parseString(commonXML, function (err, result) {
  commonObj = result;
});


module.exports = function(context) {
  // default to staging key
  var CodePushDeploymentKey = stagingDeploymentKey;

  // cordova build ios --release
  if (context.opts.options.release === true) {
    // set KEY to production one
    CodePushDeploymentKey = productionDeploymentKey;
  }

  // replace value in with proper environment specific key
  commonObj.widget.platform[1].preference[0].$.value = CodePushDeploymentKey;

  // write the xml file to the root director of the project so cordova can read it
  var xml = builder.buildObject(commonObj);
  fs.writeFileSync(__dirname + '/../config.xml', xml);
};

Tags:

Cordova