在react-native中设置环境变量?

Dam*_*uan 128 react-native

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

例:

development: 
  BASE_URL: '',
  API_KEY: '',
staging: 
  BASE_URL: '',
  API_KEY: '',
production:
  BASE_URL: '',
  API_KEY: '',
Run Code Online (Sandbox Code Playgroud)

cha*_*apa 123

而不是硬编码您的应用程序常量并切换环境(我将在稍后解释如何执行此操作),我建议使用十二个因素建议让您的构建过程定义您BASE_URL和您的API_KEY.

为了回答如何暴露你的环境react-native,我建议使用Babel的babel-plugin-transform-inline-environment-variables.

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

{
  "presets": ["react-native"],
  "plugins": [
    "transform-inline-environment-variables"
  ]
}
Run Code Online (Sandbox Code Playgroud)

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

const apiKey = process.env['API_KEY'];
Run Code Online (Sandbox Code Playgroud)

然后巴贝尔将用以下内容取而代之:

const apiKey = 'my-app-id';
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 听起来很棒的解决方案,但对我来说不适用于RN@0.37.0.`process.env`上唯一的属性是`NODE_ENV`. (6认同)
  • 对于我的w/RN 0.55.4不起作用 (5认同)
  • 适用于v0.56.每次更改环境变量时,都必须通过运行`react-native start --reset-cache`来清除bundler的缓存. (5认同)
  • 我将process.env ['API_KEY']视为未定义.任何人都可以帮我设置它 (3认同)
  • 尝试使用 gradle assembleRelease 发布时如何使用它? (3认同)
  • 请参阅下面的答案Jack Zheng ...您无法通过`process.env.API_KEY`访问变量...使用`process.env ['API_KEY']`而不是 (2认同)
  • 我有同样的问题:未定义 (2认同)
  • 也不适合我。该死的耻辱,因为这正是我正在寻找的。(55.1) (2认同)

Sla*_*cek 46

我发现最简单(不是最好最理想)的解决方案是使用react-native-dotenv.您只需.babelrc在项目根目录中将"react-native-dotenv"预设添加到您的文件中,如下所示:

{
  "presets": ["react-native", "react-native-dotenv"]
}
Run Code Online (Sandbox Code Playgroud)

创建.env文件并添加属性:

echo "SOMETHING=anything" > .env
Run Code Online (Sandbox Code Playgroud)

然后在你的项目(JS)中:

import { SOMETHING } from 'react-native-dotenv'
console.log(SOMETHING) // "anything"
Run Code Online (Sandbox Code Playgroud)

  • @SlavoVojacek我问每个环境不同的`.env`文件让我们说'staging`和`production`. (3认同)
  • @Slavo Vojacek如何使用它为`staging`和`production`配置一个`base_url`? (2认同)
  • 由于软件包中的最新更改,请更新 ypur 答案:“将导入从‘react-native-dotenv’重命名为‘@env’。” 否则,它将引发错误“找不到模块 fs”。请参阅[此问题](https://github.com/goatandsheep/react-native-dotenv/issues/20) 和[迁移指南](https://github.com/goatandsheep/react-native-dotenv/wiki /迁移指南)。 (2认同)

小智 27

在我看来,最好的选择是使用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
Run Code Online (Sandbox Code Playgroud)

然后使用它:

import Config from 'react-native-config'

Config.API_URL  // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY  // 'abcdefgh'
Run Code Online (Sandbox Code Playgroud)

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

ENVFILE=.env.staging react-native run-android
Run Code Online (Sandbox Code Playgroud)

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

cd android && ENVFILE=.env.production ./gradlew assembleRelease
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,在自述文件中它指出_请注意,此模块不会对包装的秘密进行模糊处理或加密,因此请勿将敏感密钥存储在.env中.基本上不可能阻止用户对移动应用程序机密进行逆向工程,因此请设计您的应用程序(和API) (9认同)
  • react-native-config不适用于RN 0.56,它有未解决的问题,并且已维护6个月以上。女巫杀死其在RN中的用途的问题是https://github.com/luggit/react-native-config/issues/267,这里有一些黑客手段可以使其正常工作https://github.com/luggit/react-native -配置/问题/ 285 (3认同)

toh*_*ter 22

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

但有时,您需要组件了解其环境.在这种情况下,定义一个Environment模块然后调用以获取环境变量非常简单,例如:

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
Run Code Online (Sandbox Code Playgroud)

我-component.js

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

...somewhere in your code...
var url = Environment.BASE_URL
Run Code Online (Sandbox Code Playgroud)

这将创建一个单例环境,可以从应用程序范围内的任何位置进行访问.您必须require(...)从使用环境变量的任何组件中明确显示该模块,但这是一件好事.

  • 我的问题是如何`getPlatform()`.我已经制作了这样的文件,但无法完成React Native中的逻辑 (18认同)
  • 如果您创建一个`env.js`文件,请确保在签入到存储库时将其忽略,并将使用的键(带有空字符串值)复制到另一个您要签入的`env.js.example`文件中,以便其他人签入可以更轻松地构建您的应用。如果您不小心检查了项目机密,请考虑[重写历史](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History),不仅将其从源中删除,而且将其历史删除。 (2认同)

Log*_*ter 13

我使用了__DEV__反应原生的polyfill来解决这个问题.true只要您没有为生产构建反应本机,它就会自动设置.

例如:

//vars.js

let url, publicKey;
if (__DEV__) {
  url = ...
  publicKey = ...
} else {
  url = ...
  publicKey = ...
}

export {url, publicKey}
Run Code Online (Sandbox Code Playgroud)

然后import {url} from '../vars',你将永远得到正确的.遗憾的是,如果您需要两个以上的环境,这将无法工作,但它很容易,并且不涉及向项目添加更多依赖项.

  • 这不是一个糟糕的解决方案,但也不是很好,因为它只处理布尔行为。也就是说,要么开发,要么不开发。我将如何处理两个以上的环境?您也可以使用“process.env.NODE_ENV”,因为它提供“开发”或“生产”。大多数人需要使用开发、质量保证、登台、生产等来提升应用程序。 (3认同)

小智 9

按着这些次序

  1. npm 安装react-native-dotenv
  2. 设置带有一些变量名称的 .env 文件,即 APP_NAME="my-app"
  3. 修改bable.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ["module:react-native-dotenv", {
      "envName": "APP_ENV",
      "moduleName": "@env",
      "path": ".env",
      "safe": false,
      "allowUndefined": true,
      "verbose": false
    }]
  ]
};
Run Code Online (Sandbox Code Playgroud)

  1. 重新启动所有应用程序
  2. 试试这个import {APP_NAME} from '@env'。如果这不起作用,那么就做这个const APP_NAME = process.env['APP_NAME'];

干杯:)


Ton*_*haz 6

我为相同的问题创建了一个预构建脚本,因为我需要一些不同的 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')
})
Run Code Online (Sandbox Code Playgroud)

我创建了一个自定义npm run scripts来执行react-native run..

我的包-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",
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后在我的服务组件中只需导入自动生成的文件:

import config from '../constants/config'

fetch(`${config.API_URL}/login`, params)
Run Code Online (Sandbox Code Playgroud)


Jos*_*das 5

用于设置环境变量的特定方法会因CI服务,构建方法,所使用的平台和工具而异。

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

#!/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
Run Code Online (Sandbox Code Playgroud)

提示:不要忘记添加env.js.gitignore如此配置和秘密开发过程中没有签入源代码控制意外。

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


小智 5

在打字稿中

  1. 安装库:react-native-dotenv

    yarn add -D react-native-dotenv
    yarn add -D @types/react-native-dotenv
    
    Run Code Online (Sandbox Code Playgroud)
  2. 配置文件babel.config.js

    module.exports = {
    ...
      plugins: ['module:react-native-dotenv'],
    ...
    };
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建文件.env

    API_URL="api.com"
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建文件夹types,然后创建文件env.d.ts

    declare module '@env' {
      export const API_URL: string;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 添加文件夹typestsconfig.json

    {
      ...
      "compilerOptions": {
        ...
        "typeRoots": ["./src/types/"]
        ...
      }
      ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 好的,现在尝试一下:

    import {API_URL} from '@env'
    console.log(API_URL)
    
    Run Code Online (Sandbox Code Playgroud)