Использование переменных среды / параметризация конфигурации.XML

Я создаю проект ionic / cordova, используя плагин cordova-plugin-facebook4 для доступа к аутентификации Facebook. В config.xml это выглядит так:

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

это работает нормально, но APP_ID мы используем для приложения dev, и у нас есть отдельное приложение facebook для других сред, таких как QA.

есть ли способ параметризовать эти переменные в config.xml и заменить их как часть шага сборки? Что-то вроде:

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

... а потом беги!--5--> или что-то подобное.

Я не вижу ничего в документации cordova, что позволяет вам это делать.

4 ответов


как вы упомянули в сообщении, в официальной документации cordova не так много документации об этом. Потратив некоторое время на этот анализ, я пришел к следующему выводу:--5-->

существует некоторая минимальная помощь, доступная для параметризации переменных плагина, доступных в config.xml. Это может быть достигнуто с помощью переменных предпочтений, как указано в официальный Кордова ссылке. Но проблема с этим подходом заключается в том, что его работа зависит от того, как на плагин закодирован.

Я пробовал этот подход с плагином facebook, но он не работал : (я пробовал, как показано ниже:

<preference name="MY_CUSTOM_STRING" default="12345678901234567" />
    <plugin name="cordova-plugin-facebook4" spec="~1.7.1">
        <variable name="APP_ID">$MY_CUSTOM_STRING</variable>
        <variable name="APP_NAME" value="My_Appy_App"/>
    </plugin>

попробовал тот же подход для плагина google maps, и он сработал :) я попробовал, как показано ниже:

<preference name="MY_CUSTOM_STRING" default="12345678901234567" />
<plugin name="cordova-plugin-googlemaps" spec="~1.3.9">
    <variable name="API_KEY_FOR_ANDROID">$MY_CUSTOM_STRING</variable>
</plugin>

таким образом, все, что я мог заключить, это то, что подход параметризации зависит от основного кода плагина.

в случае плагина facebook, если вы хотите параметризовать APP_ID переменная, тогда я думаю, что крючки-это способ приступать. Даже простой пакетный файл windows для замены совпадения строк должен быть прекрасным, и его можно вызвать при предварительном действии сборки для достижения того, что вам требуется. Надеюсь, это поможет.

обновление:

Я согласен с комментариями Брэндона.

с ограниченным временем я смог придумать крючок cordova, который решает эту проблему. Это может быть грубый способ, и он также может быть уточнен, но пока этот подход работает нормально. Разместили крючок как пример приложения в my страница github и файл README имеет полную информацию об этом. Надеюсь, это поможет. Держи меня в курсе.


решение@Ghandi с использованием крючков cordova является хорошим примером того, как это может быть достигнуто, хотя это специально windows, только поскольку он использует пакетный файл и PowerShell для сценария крючка.

в качестве кросс-платформенного решения вы можете использовать какой-то инструмент сборки поверх cordova. Для проекта над которым я работаю, у нас есть проект Cordova в каталоге и уже с помощью залпом чтобы построить остальную часть нашего приложения, чтобы мы изменили нашу задачу, что копирует наши активы cordova в каталог сборки, чтобы он также выполнял поиск и замену на config.xml. Он вытягивает замены из переменных среды и использует библиотеку dotenv для загрузки среды из .env файл (который не проверяется в репозитории).

var gulp = require('gulp'),
  replace = require('gulp-replace'),
  gutil = require('gulp-util'),
  filter = require('gulp-filter'),
  path = require('path'),
  dotenv = require('dotenv'),

  argv = require('yargs').argv,
  isRelease = !!(typeof argv.release !== 'undefined' ? argv.release : (typeof argv.r !== 'undefined' ? argv.r : false));

gulp.task('cordova_assets', ['clean', 'templates'], function() {
  dotenv.config({path: path.join(__dirname, 'cordova', '.env'), silent: true});
  var f = filter(['cordova/config.xml'], {restore: true});

  return gulp.src(['cordova/**/*'], {base: './'})
    .pipe(f)
    .pipe(replace(/$$([A-Z0-9_]+)/gi, function(substr, varname) {
      var repl = '';
      if(!isRelease && typeof process.env[varname + '_DEBUG'] !== 'undefined')
        repl = process.env[varname + '_DEBUG'];
      else if(isRelease && typeof process.env[varname + '_RELEASE'] !== 'undefined')
        repl = process.env[varname + '_RELEASE'];
      else if(typeof process.env[varname] !== 'undefined')
        repl = process.env[varname];
      else {
        throw new gutil.PluginError('cordova_config', {
          message: 'expected but could not find the environment variables "' + varname +
          '" or "' + varname + '_' + (isRelease ? 'RELEASE' : 'DEBUG') + '" which is used in cordova/config.xml. ' +
          'Add it to cordova/.env or specify them explicitly when running the build command.'
        });
      }

      console.log('replacing "%s" with "%s"', substr, repl);
      return repl;
    }))
    .pipe(f.restore)
    .pipe(gulp.dest('build'));
});

он заменит любые переменные в config.xml, начинающийся с двух знаков доллара и состоящий из буквенно-цифровых символов и подчеркиваний со значением соответствующей переменной среды, если она существует (и выдает ошибку, если это не так). Кроме того, вы можете суффикс переменной в конфиге.xml с любым _DEBUG или _RELEASE и он будет использовать эти значения соответствующим образом.

он предполагает следующую структуру проекта:

  • /
    • cordova
      • config.xml
      • ... (остальная часть вашей установки cordova)
      • .env (содержит переменные окружения)
    • build (каталог сборки и окончательный вывод приложения cordova)

я достиг этого, создавая шаблон config.xml (файл config.tpl.xml) и before_prepare cordova hook, чтобы заменить переменные в шаблоне правильными значениями и сохранить сгенерированный контент в config.xml.

крючок cordova использует пакет npm es6-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/ каталог для различных сред, которые выбираются исходя из NODE_ENV значение, определенное при построении cordova. Например, если 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>

просто имейте в виду, что вам нужно добавить автоматические изменения cordova в config.xml к шаблону (например, добавление плагина), но это намного лучше (и, в моем случае, реже), чем изменение переменные перед каждой сборкой с разными средами и гораздо менее подвержены ошибкам, хотя и не идеальны.

обновление (2017-10-13)

теперь, когда я добавляю / удаляю Плагины, файл шаблона xml также обновляется. Я только что добавил крючки, описанные здесь.


в моей практике мы просто ставим два файла name config.xml и config.beta.xml для отдельных переменных.

запустить shell mv config.beta.xml до cordova platform add xxx Если создание бета-версии apk.