我正在使用react-native来构建一个跨平台的应用程序,但我不知道如何设置环境变量,以便我可以有不同的常量为不同的环境。

例子:

development: 
  BASE_URL: '',
  API_KEY: '',
staging: 
  BASE_URL: '',
  API_KEY: '',
production:
  BASE_URL: '',
  API_KEY: '',

当前回答

在我看来,最好的选择是使用react-native-config。 支持12因子。

我发现这个包非常有用。您可以设置多个环境,例如开发、登台、生产。

在Android的情况下,变量也可以在Java类,gradle, AndroidManifest.xml等。 在iOS中,变量也可以在Obj-C类,Info.plist中使用。

你只需要创建文件

.env.development .env.staging .env.production

你用键和值填充这些文件,比如

API_URL=https://myapi.com
GOOGLE_MAPS_API_KEY=abcdefgh

然后使用它:

import Config from 'react-native-config'

Config.API_URL  // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY  // 'abcdefgh'

如果你想使用不同的环境,你基本上像这样设置ENVFILE变量:

ENVFILE=.env.staging react-native run-android

或者为生产组装应用程序(在我的情况下是android):

cd android && ENVFILE=.env.production ./gradlew assembleRelease

其他回答

与其硬编码你的应用常量并在环境上进行切换(我将在稍后解释如何做到这一点),我建议使用12因素建议,让你的构建过程定义你的BASE_URL和API_KEY。

要回答如何将您的环境暴露为react-native,我建议使用Babel的Babel -plug -transform-inline-environment-variables。

为了让它工作,你需要下载这个插件,然后你需要设置一个.babelrc,它应该看起来像这样:

{
  "presets": ["react-native"],
  "plugins": [
    "transform-inline-environment-variables"
  ]
}

因此,如果你通过运行API_KEY=my-app-id react-native bundle(或start, run-ios,或run-android)来编译你的react-native代码,那么你所要做的就是让你的代码看起来像这样:

const apiKey = process.env['API_KEY'];

然后巴别塔会用:

const apiKey = 'my-app-id';

用于设置环境变量的具体方法将因您使用的CI服务、构建方法、平台和工具而异。

如果你正在使用Buddybuild for CI来构建应用程序和管理环境变量,并且你需要从JS中访问配置,创建一个带有键(空字符串值)的env.js.example用于签入源代码控制,并在构建时在后克隆步骤中使用Buddybuild生成一个env.js文件,从构建日志中隐藏文件内容,如下所示:

#!/usr/bin/env bash

ENVJS_FILE="$BUDDYBUILD_WORKSPACE/env.js"

# Echo what's happening to the build logs
echo Creating environment config file

# Create `env.js` file in project root
touch $ENVJS_FILE

# Write environment config to file, hiding from build logs
tee $ENVJS_FILE > /dev/null <<EOF
module.exports = {
  AUTH0_CLIENT_ID: '$AUTH0_CLIENT_ID',
  AUTH0_DOMAIN: '$AUTH0_DOMAIN'
}
EOF

提示:不要忘记将env.js添加到.gitignore中,这样在开发过程中配置和秘密就不会意外地检入源代码控制。

然后,您可以使用Buddybuild变量(例如buddybuild_variables)管理文件的编写方式,以更好地控制在构建时如何生成配置。

在我看来,最好的选择是使用react-native-config。 支持12因子。

我发现这个包非常有用。您可以设置多个环境,例如开发、登台、生产。

在Android的情况下,变量也可以在Java类,gradle, AndroidManifest.xml等。 在iOS中,变量也可以在Obj-C类,Info.plist中使用。

你只需要创建文件

.env.development .env.staging .env.production

你用键和值填充这些文件,比如

API_URL=https://myapi.com
GOOGLE_MAPS_API_KEY=abcdefgh

然后使用它:

import Config from 'react-native-config'

Config.API_URL  // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY  // 'abcdefgh'

如果你想使用不同的环境,你基本上像这样设置ENVFILE变量:

ENVFILE=.env.staging react-native run-android

或者为生产组装应用程序(在我的情况下是android):

cd android && ENVFILE=.env.production ./gradlew assembleRelease

我使用babel-plugin-transform-inline-environment-variables。

我所做的是将配置文件放在S3中的不同环境中。

s3://example-bucket/dev-env.sh
s3://example-bucket/prod-env.sh
s3://example-bucket/stage-env.sh

每个env文件:

FIRSTENV=FIRSTVALUE
SECONDENV=SECONDVALUE

之后,我在包中添加了一个新脚本。Json,它运行用于捆绑的脚本

if [ "$ENV" == "production" ]
then
  eval $(aws s3 cp s3://example-bucket/prod-env.sh - | sed 's/^/export /')
elif [ "$ENV" == "staging" ]
then
  eval $(aws s3 cp s3://example-bucket/stage-env.sh - | sed 's/^/export /')
else
  eval $(aws s3 cp s3://example-bucket/development-env.sh - | sed 's/^/export /')
fi

react-native start

在你的应用中,你可能会有一个配置文件,它有:

const FIRSTENV = process.env['FIRSTENV']
const SECONDENV = process.env['SECONDENV']

它将被巴别塔所取代:

const FIRSTENV = 'FIRSTVALUE'
const SECONDENV = 'SECONDVALUE'

记住你必须使用过程。env['STRING'] NOT process.env.STRING否则将不能正确转换。

我认为像下面这样的库可以帮助您解决谜题中缺失的部分,即getPlatform()函数。

https://github.com/joeferraro/react-native-env

const EnvironmentManager = require('react-native-env');

// read an environment variable from React Native
EnvironmentManager.get('SOME_VARIABLE')
  .then(val => {
    console.log('value of SOME_VARIABLE is: ', val);

  })
  .catch(err => {
    console.error('womp womp: ', err.message);
  });

我所看到的唯一问题是,这是异步代码。有一个拉请求来支持getSync。也来看看吧。

https://github.com/joeferraro/react-native-env/pull/9