我正在使用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: '',
当前回答
为了解决这个问题,我使用了react-native中内置的__DEV__ polyfill。只要您不是为生产构建react native,它就会自动设置为true。
例如:
//vars.js
let url, publicKey;
if (__DEV__) {
url = ...
publicKey = ...
} else {
url = ...
publicKey = ...
}
export {url, publicKey}
然后只需导入{url}从'../vars',你总是会得到正确的。不幸的是,如果你想要两个以上的环境,这就行不通了,但它很简单,而且不需要向你的项目添加更多的依赖项。
其他回答
我使用react-native-config为我的项目设置了多个环境。README文件非常清楚地解释了如何在项目中配置库。只要确保实现Android部分的额外步骤即可。
另外,在设置多个环境时,请确保在包中指定正确的启动命令。Json,基于您的系统终端。我在windows笔记本电脑中开发了Android代码,在Macbook中开发了iOS代码,所以我各自的启动命令都在包中。Json是-
"scripts": {
"android:dev": "SET ENVFILE=.env.dev && react-native run-android",
"android:prod": "SET ENVFILE=.env.prod && react-native run-android",
"ios:dev": "ENVFILE=.env.dev react-native run-ios",
"ios:prod": "ENVFILE=.env.prod react-native run-ios",
},
如果您只需要维护一个.env文件,请考虑使用 react-native-dotenv是一个较轻的选择,尽管我在为这个库设置多个.env文件时遇到了一些问题。
我已经为相同的问题创建了一个预构建脚本,因为我需要一些不同环境的不同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)
与其硬编码你的应用常量并在环境上进行切换(我将在稍后解释如何做到这一点),我建议使用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';
我发现最简单(不是最好或最理想)的解决方案是使用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"
如果你使用的是Expo,根据文档https://docs.expo.io/guides/environment-variables/有两种方法
方法#1 -在应用程序清单(app.json)中使用.extra道具:
在你的app.json文件中
{
expo: {
"slug": "my-app",
"name": "My App",
"version": "0.10.0",
"extra": {
"myVariable": "foo"
}
}
}
然后要访问你的代码(即App.js)上的数据,只需导入expo-constants:
import Constants from 'expo-constants';
export const Sample = (props) => (
<View>
<Text>{Constants.manifest.extra.myVariable}</Text>
</View>
);
这个选项是一个很好的内置选项,不需要安装任何其他包。
方法#2 -使用Babel“替换”变量。这是您可能需要的方法,特别是当您正在使用裸工作流时。其他的答案已经提到了如何使用babel-plugin-transform-inline-environment-variables来实现它,但是我将在这里留下一个官方文档的链接来说明如何实现它:https://docs.expo.io/guides/environment-variables/#using-babel-to-replace-variables