【问题标题】:Cordova config.xml environment variablesCordova config.xml 环境变量
【发布时间】:2017-09-21 13:43:47
【问题描述】:

情景:

我正在构建一个 Ionic3 应用程序,而我的 config.xml 有一些我希望能够根据我的环境更改的数据(例如,我希望我的 facebook 应用程序 ID 具有不同的开发值,分期和生产)。

我创建了一个模板config.xml(文件是config.tpl.xml)和一个before_preparecordova钩子来用正确的值替换模板中的变量并将生成的内容保存在config.xml中。

cordova 钩子使用npmes6-template-strings

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

钩子是:

#!/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);

我在src/environments/ 目录中有不同环境的文件,这些文件是根据我构建cordova 时定义的NODE_ENV 值选择的。例如,如果NODE_ENV=prod(生产),那么它将使用文件environment.prod.json

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

钩子执行时,这部分在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>

变成:

<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>

问题:

到目前为止一切顺利。问题是当对config.xml进行一些自动更改(比如添加插件)时,cordova.tpl.xml并没有反映出来,所以我必须记得手动进行更改。

虽然现在完成的方式仍然比以前必须添加每个环境变量要好得多(这是维护的噩梦并且容易出错),但我仍然必须在每次添加/更改/删除时更改模板一个插件(不是那么频繁,忘记了也容易发现问题,但离理想还差得很远)。

我的问题:

我想知道是否有办法避免这些手动更改,但要像现在一样继续使用环境变量。

如果可能的话,可以将config.xml 的自动更改改为config.tpl.xml(比如添加带有--save 的插件时),但我没有找到任何关于cordova 的选项这个。

或者使用config.xml作为模板并将其发送到定义了变量的另一个地方(例如www/config.xml),并在另一个位置使用config.xml来构建应用程序(不是config.xml 在根中,即模板)。我只会更改我的钩子中的srcdest 文件(分别更改为config.xmlwww/config.xml)。但我也没有找到实现这一点的方法。

对此有什么想法吗?

(它不需要是特定于 Ionic 的解决方案。)

更新 (2017-10-13)

根据Bobby 的回答,我在安装和卸载插件时都实现了我想要的。我创建了 4 个钩子:after_plugin_addafter_plugin_rmbefore_plugin_addbefore_plugin_rm

before 挂钩将模板 (config.tpl.xml) 复制到 config.xml 文件中,after 挂钩则相反。

before_plugin_addbefore_plugin_rm 钩子如下:

#!/usr/bin/env node
var fs = require('fs');
var path = require('path');

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

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

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

after_plugin_addafter_plugin_rm 挂钩几乎相同,只是交换了 FILES.SRCFILES.DEST 值。

【问题讨论】:

  • 谢谢!注意:这条线 var ROOT_DIR = process.argv[2]; 在我的情况下不起作用,因为 process.argv[2] 被解析为“准备”。在我的情况下有效的是var ROOT_DIR = '';。我正在使用 Ionic 4 和 Cordova CLI 9.0。
  • 另一个问题:你是否将config.xml添加到.gitignore?从我的角度来看,不签入是有意义的。
  • @KlemensZleptnig 我将config.yml 添加到.gitignore。我不知道如何在 Ionic4 挂钩中获取根目录:/ 不过,在科尔多瓦项目中,上述内容应该可以工作。您将它们用作科尔多瓦钩子还是 ionic 在幕后处理它?我认为 Ionic4 正在添加参数。您可以尝试像console.log('1', process.argv[1])console.log('2', process.argv[2])console.log('3', process.argv[3]) 等一样记录它们。
  • 但是在安装插件的过程中,config.tpl.yml 变成config.xml 的文件不是交换的想法,以便将新插件添加到其中,并且在安装后恢复? ???根据这个逻辑——如果我理解正确的话——在安装过程中,config.xml 中会有变量。
  • @KlemensZleptnig 这个话题有点老了,所以我忘了:P。似乎取决于您放置变量的位置(在您的情况下,它表示路径)cordova 可能会出错,所以我不知道您是否应该使用我提到的钩子。 我建议你做的事情(这是我通常做的事情),是直接在文件config.tpl.yml中定义插件,而不是从命令行添加它们,这样准备步骤完成后,插件已安装,您不需要挂钩,也不需要将代码从 config.xml 复制到模板。

标签: cordova ionic3


【解决方案1】:

一种解决方案是为 before_plugin_installafter_plugin_install 创建挂钩。

On before_plugin_install copy the cordova.tpl.xml to cordova.xml.
... Plugin is installed ...
On after_plugin_install copy cordova.xml to cordova.tpl.xml

【讨论】:

  • 你是如何将 ${FACEBOOK_APP_ID} 变量保存在 after_hooks 的 tpl 文件中的?
  • ${FACEBOOK_APP_ID} 是模板的一部分。因此,您将模板复制到原始文件的顶部。安装新插件。这不应该影响 ${FACEBOOK_APP_ID} 变量。然后再次将此文件作为模板。
猜你喜欢
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
相关资源
最近更新 更多