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

例子:

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

当前回答

不要传递像VAR=value react-native run-android或VAR=value react-native run-ios这样的变量。这些变量只有当我们在开始命令中传递它们时才可以访问,即VAR=value react-native start——reset-cache。

你可以通过3个简单的步骤来实现这一点:-

通过运行npm i babel-plugin-transform-inline-environment-variables——save-dev安装babel-plugin-transform-inline-environment-variables。 在.bablerc或babel.config.js中添加"plugins": ["transform-inline-environment-variables"] 在启动metro bundle时传递变量,即VAR=value react-native start -reset-cache,不要在react-native run-android或react-native run-ios命令中传递这些变量。

请记住,使用——reset-cache标志是必需的,否则变量的变化将不会被应用。

其他回答

React native没有全局变量的概念。 它严格执行模块化范围,以促进组件的模块化和可重用性。

但是,有时您需要组件能够感知它们所处的环境。在这种情况下,定义一个环境模块非常简单,然后组件可以调用它来获取环境变量,例如:

environment.js

var _Environments = {
    production:  {BASE_URL: '', API_KEY: ''},
    staging:     {BASE_URL: '', API_KEY: ''},
    development: {BASE_URL: '', API_KEY: ''},
}

function getEnvironment() {
    // Insert logic here to get the current platform (e.g. staging, production, etc)
    var platform = getPlatform()

    // ...now return the correct environment
    return _Environments[platform]
}

var Environment = getEnvironment()
module.exports = Environment

my-component.js

var Environment = require('./environment.js')

...somewhere in your code...
var url = Environment.BASE_URL

这创建了一个单例环境,可以从应用范围内的任何地方访问。你必须显式地要求(…)使用环境变量的任何组件的模块,但这是一件好事。

对于最新的RN版本,您可以使用这个本机模块:https://github.com/luggit/react-native-config

我使用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)

遵循以下步骤

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'];

欢呼:)