我正在使用react-native来构建一个跨平台的应用程序,但我不知道如何设置环境变量,以便我可以有不同的常量为不同的环境。
例子:
development:
BASE_URL: '',
API_KEY: '',
staging:
BASE_URL: '',
API_KEY: '',
production:
BASE_URL: '',
API_KEY: '',
我正在使用react-native来构建一个跨平台的应用程序,但我不知道如何设置环境变量,以便我可以有不同的常量为不同的环境。
例子:
development:
BASE_URL: '',
API_KEY: '',
staging:
BASE_URL: '',
API_KEY: '',
production:
BASE_URL: '',
API_KEY: '',
当前回答
我认为像下面这样的库可以帮助您解决谜题中缺失的部分,即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
其他回答
为了解决这个问题,我使用了react-native中内置的__DEV__ polyfill。只要您不是为生产构建react native,它就会自动设置为true。
例如:
//vars.js
let url, publicKey;
if (__DEV__) {
url = ...
publicKey = ...
} else {
url = ...
publicKey = ...
}
export {url, publicKey}
然后只需导入{url}从'../vars',你总是会得到正确的。不幸的是,如果你想要两个以上的环境,这就行不通了,但它很简单,而且不需要向你的项目添加更多的依赖项。
我已经为相同的问题创建了一个预构建脚本,因为我需要一些不同环境的不同API端点
const fs = require('fs')
let endPoint
if (process.env.MY_ENV === 'dev') {
endPoint = 'http://my-api-dev/api/v1'
} else if (process.env.MY_ENV === 'test') {
endPoint = 'http://127.0.0.1:7001'
} else {
endPoint = 'http://my-api-pro/api/v1'
}
let template = `
export default {
API_URL: '${endPoint}',
DEVICE_FINGERPRINT: Math.random().toString(36).slice(2)
}
`
fs.writeFile('./src/constants/config.js', template, function (err) {
if (err) {
return console.log(err)
}
console.log('Configuration file has generated')
})
我已经创建了一个自定义的npm运行脚本来执行反应本机运行..
我package-json
"scripts": {
"start-ios": "node config-generator.js && react-native run-ios",
"build-ios": "node config-generator.js && react-native run-ios --configuration Release",
"start-android": "node config-generator.js && react-native run-android",
"build-android": "node config-generator.js && cd android/ && ./gradlew assembleRelease",
...
}
然后在我的服务组件中导入自动生成的文件:
import config from '../constants/config'
fetch(`${config.API_URL}/login`, params)
我使用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否则将不能正确转换。
我发现最简单(不是最好或最理想)的解决方案是使用react-native-dotenv。你只需在你的.babelrc文件的根目录下添加"react-native-dotenv"预设,如下所示:
{
"presets": ["react-native", "react-native-dotenv"]
}
创建一个.env文件并添加属性:
echo "SOMETHING=anything" > .env
然后在你的项目(JS):
import { SOMETHING } from 'react-native-dotenv'
console.log(SOMETHING) // "anything"
遵循以下步骤
NPM安装react-native-dotenv 用一些变量名设置。env文件,例如APP_NAME="my-app" 修改bable.config.js
模块。出口= { 预设:['模块:metro-react-native-babel-preset '), 插件:[ ["模块:react-native-dotenv ", { :“envName APP_ENV”, :“moduleName @env”, “路径”:“.env”, “安全”:假的, “allowUndefined”:没错, “详细”:假的 }) ] };
重新启动所有应用程序 尝试从“@env”导入{APP_NAME}。如果这不起作用,那么执行这个const APP_NAME = process.env['APP_NAME'];
欢呼:)