Cordova:在config.xml中使用环境变量

时间:2018-02-14 06:46:05

标签: javascript cordova webpack environment-variables

我认为应该避免暴露API密钥。如何在构建期间根据不同的环境在config.xml中使用环境变量作为参数?

例如,

<preference name="TwitterConsumerKey" value="$TWITTER_KEY" />
<preference name="TwitterConsumerSecret" value="$TWITTER_SECRET" />

假设:TWITTER_KEYTWITTER_SECRET应放在具有不同值的开发和生产环境文件中

我目前正在使用如下的自定义webpack配置。

const chalk = require("chalk");
const fs = require('fs');
const path = require('path');
const useDefaultConfig = require('@ionic/app-scripts/config/webpack.config.js');

let env = process.env.IONIC_ENV;

useDefaultConfig.prod.resolve.alias = {
  "@projectName/env": path.resolve(environmentPath('prod'))
};

useDefaultConfig.dev.resolve.alias = {
  "@projectName/env": path.resolve(environmentPath('dev')),
};

if (env !== 'prod' && env !== 'dev') {
  // Default to dev config
  useDefaultConfig[env] = useDefaultConfig.dev;
  useDefaultConfig[env].resolve.alias = {
    "@projectName/env": path.resolve(environmentPath(env))
  };
}

function environmentPath(env) {
  var filePath = './src/environments/environment' + (env === 'prod' ? '' : '.' + env) + '.ts';
  if (!fs.existsSync(filePath)) {
    console.log(chalk.red('\n' + filePath + ' does not exist!'));
  } else {
    return filePath;
  }
}

module.exports = function () {
  return useDefaultConfig;
};

我应该在自定义配置中包含哪些内容才能让事情发生?

修改

environment.ts

export const environment = {
  mode: 'Production',
  production: true,
  firebase: {
    apiKey: "SOME KEY",
    authDomain: "prod.firebaseapp.com",
    databaseURL: "https://prod.firebaseio.com",
    projectId: "prod",
    storageBucket: "prod.appspot.com",
    messagingSenderId: "SOME ID"
  },

  // I'd like to use these key values in config.xml during build time
  TWITTER_KEY: "SOME KEY", 
  TWITTER_SECRET: "SOME SECRET KEY"
};

environment.dev.ts

export const environment = {
  mode: 'Development',
  production: false,
  firebase: {
     apiKey: "SOME KEY",
     authDomain: "dev.firebaseapp.com",
     databaseURL: "https://dev.firebaseio.com",
     projectId: "dev",
     storageBucket: "dev.appspot.com",
     messagingSenderId: "SOME ID"
  },

  // Use these key values as well
  TWITTER_KEY: "SOME KEY", 
  TWITTER_SECRET: "SOME SECRET KEY"
};

例如,ionic cordova build ios --dev将使用environment.dev.ts个变量。另一方面,ionic cordova build ios --prod将使用environment.ts变量。

1 个答案:

答案 0 :(得分:1)

我只是通过以编程方式加载和解析config.xml(或我需要的任何东西,如.git/HEAD resp。./git/refs/heads/*来获取最新的提交哈希)来解决这样的问题;考虑你的environment.{dev,prod}.ts它可能是(在你的webpack配置中):

// just get the environment files:
const devEnvironment = require('/path/to/environment.dev.ts').environment;
const prodEnvironment = require('/path/to/environment.prod.ts').environment;

//...

const envConfig = env === 'prod' ? prodEnvironment : devEnvironment;

var twitterKey;
var twitterSecret;
// load the config.xml
var configXmlFile = fs.readFileSync(path.join(__dirname, './config.xml'));
// get it's rows
var configRows = configXmlFile.toString().split(/\n/);
// traverse the rows
configRows.forEach(function (row) {
    // check if the row do have what we're looking for
    if (row.indexOf('TwitterConsumerKey') !== -1) {
        // get the environment variable name
        var twitterKeyVarName = row.replace(/.*value="\$([^"]*)".*/, '$1');
        // get the variable value - environment file variant
        twitterKey = envConfig[twitterKeyVarName];
    }
    else if (row.indexOf('TwitterConsumerSecret') !== -1) {
        var twitterSecretVarName = row.replace(/.*value="\$([^"]*)".*/, '$1');
        twitterSecret = envConfig[twitterSecretVarName];
    }
});

可能会以更优雅的方式写出,但这就是想法。