Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
344 views
in Technique[技术] by (71.8m points)

javascript - Using environment variables / parameterizing config.xml

I am building an ionic/cordova project using the cordova-plugin-facebook4 plugin for Facebook authentication access. In config.xml this looks like:

<plugin name="cordova-plugin-facebook4" spec="~1.7.1">
  <variable name="APP_ID" value="1234567890123456"/>
  <variable name="APP_NAME" value="My_Appy_App"/>
</plugin>

This works okay, but the APP_ID we are using is for the dev app and we have a separate facebook app for other environments such as QA.

Is there any way to parameterize these variables in config.xml and have them be replaced as part of a build step? Something like:

<plugin name="foo" spec="~0.0.0">
  <variable name="bar" value="${env.APP_ID}"/>
</plugin>

... and then run APP_ID=baz ionic build android or something like that.

I don't see anything in the cordova documentation that allows you to do this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've achieved that creating 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 cordova hook uses the npm package es6-template-strings:

npm install es6-template-strings --save-dev

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 have files in the src/environments/ directory for different environments, that are chosen based on the NODE_ENV value that is defined when I build cordova. For example, if NODE_ENV=prod (production), then it would use the file environment.prod.json:

{
    ...
    "FACEBOOK_APP_ID": "11111111",
    "FACEBOOK_APP_NAME": "My Facebook App Name",
    ...
    "PUSH_SENDER_ID": "22222222",
    ...
}

When the hook is executed, this part in the cordova.tpl.xml:

<plugin name="cordova-plugin-facebook4" spec="~1.7.4">
    <variable name="APP_ID" value="${FACEBOOK_APP_ID}" />
    <variable name="APP_NAME" value="${FACEBOOK_APP_NAME}" />
</plugin>
<plugin name="phonegap-plugin-push" spec="~1.9.2">
    <variable name="SENDER_ID" value="${PUSH_SENDER_ID}" />
</plugin>

becomes like:

<plugin name="cordova-plugin-facebook4" spec="~1.7.4">
    <variable name="APP_ID" value="11111111" />
    <variable name="APP_NAME" value="My Facebook App Name" />
</plugin>
<plugin name="phonegap-plugin-push" spec="~1.9.2">
    <variable name="SENDER_ID" value="22222222" />
</plugin>

Just have in mind that you need to add the automatic cordova changes to config.xml to the template (like adding a plugin), but that is much better (and, in my case, less frequent) than having to change the variables before each build with different environments and much less error prone, although it is not ideal.

Update (2017-10-13)

Now when I add/remove plugins, the xml template file is also updated. I've just added the hooks described here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...