react node instalar entorno configurar react-native

react native - node - Configuración de la variable de entorno en react-native?



instalar react native en windows (15)

Estoy usando react-native para construir una aplicación multiplataforma, pero no sé cómo configurar la variable de entorno para poder tener diferentes constantes para diferentes entornos.

Ejemplo:

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


Creo que algo como la siguiente biblioteca podría ayudarlo a resolver la parte faltante del rompecabezas, la función 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); });

El único problema que veo con esto es que es un código asíncrono. Hay una solicitud de extracción para admitir getSync. Compruébalo también.

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


El método específico utilizado para establecer variables de entorno variará según el servicio de CI, el enfoque de compilación, la plataforma y las herramientas que esté utilizando.

Si está utilizando Buddybuild para CI para construir una aplicación y administrar variables de entorno , y necesita acceso a la configuración desde JS, cree un env.js.example claves (con valores de cadena vacíos) para el registro en el control de origen, y use Buddybuild para producir un archivo env.js en el momento de la compilación en el paso post-clone , ocultando el contenido del archivo de los registros de compilación, así:

#!/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

Consejo: No olvide agregar env.js a .gitignore para que la configuración y los secretos no se verifiquen accidentalmente en el control de origen durante el desarrollo.

Luego puede administrar cómo se escribe el archivo usando las variables Buddybuild como BUDDYBUILD_VARIANTS , por ejemplo, para obtener un mayor control sobre cómo se produce su configuración en el momento de la compilación.


En lugar de codificar constantemente las constantes de su aplicación y hacer un cambio en el entorno (explicaré cómo hacerlo en un momento), sugiero usar la sugerencia de doce factores para que su proceso de compilación defina su BASE_URL y su API_KEY .

Para responder cómo exponer su entorno a react-native , sugiero usar las babel-plugin-transform-inline-environment-variables Babel.

Para que esto funcione, debe descargar el complemento y luego deberá configurar un .babelrc y debería verse así:

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

Entonces, si transpila su código react-native ejecutando API_KEY=my-app-id react-native bundle (o start, run-ios o run-android), todo lo que tiene que hacer es hacer que su código se vea así:

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

Y luego Babel lo reemplazará con:

const apiKey = ''my-app-id'';

¡Espero que esto ayude!


En mi opinión, la mejor opción es usar react-native-config . Es compatible con 12 factores .

Encontré este paquete extremadamente útil. Puede configurar múltiples entornos, por ejemplo, desarrollo, puesta en escena, producción.

En el caso de Android, las variables están disponibles también en las clases Java, gradle, AndroidManifest.xml, etc. En el caso de iOS, las variables también están disponibles en las clases Obj-C, Info.plist.

Simplemente creas archivos como

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

Rellena estos archivos con clave, valores como

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

y luego solo utilízalo:

import Config from ''react-native-config'' Config.API_URL // ''https://myapi.com'' Config.GOOGLE_MAPS_API_KEY // ''abcdefgh''

Si desea utilizar diferentes entornos, básicamente configura la variable ENVFILE de esta manera:

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

o para ensamblar aplicaciones para producción (Android en mi caso):

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


Es posible acceder a las variables con process.env.blabla lugar de process.env[''blabla''] . Recientemente lo hice funcionar y comenté cómo lo hice en un problema en GitHub porque tuve algunos problemas con el caché en función de la respuesta aceptada. Here está el problema.


He creado un script de compilación previa para el mismo problema porque necesito algunos puntos finales de API diferentes para los diferentes entornos.

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'') })

Y he creado npm run scripts personalizados para ejecutar la ejecución de reacción nativa.

Mi paquete-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", ... }

Luego, en mis componentes de servicios, simplemente importe el archivo generado automáticamente:

import config from ''../constants/config'' fetch(`${config.API_URL}/login`, params)


La respuesta de @ chapinkapa es buena. Un enfoque que he tomado desde que Mobile Center no admite variables de entorno es exponer la configuración de compilación a través de un módulo nativo:

En Android:

@Override public Map<String, Object> getConstants() { final Map<String, Object> constants = new HashMap<>(); String buildConfig = BuildConfig.BUILD_TYPE.toLowerCase(); constants.put("ENVIRONMENT", buildConfig); return constants; }

o en ios:

override func constantsToExport() -> [String: Any]! { // debug/ staging / release // on android, I can tell the build config used, but here I use bundle name let STAGING = "staging" let DEBUG = "debug" var environment = "release" if let bundleIdentifier: String = Bundle.main.bundleIdentifier { if (bundleIdentifier.lowercased().hasSuffix(STAGING)) { environment = STAGING } else if (bundleIdentifier.lowercased().hasSuffix(DEBUG)){ environment = DEBUG } } return ["ENVIRONMENT": environment] }

Puede leer la configuración de compilación sincrónicamente y decidir en Javascript cómo se comportará.


La solución más simple (no la mejor o la ideal ) que encontré fue usar react-native-dotenv . Simplemente agregue el preset "react-native-dotenv" a su archivo .babelrc en la raíz del proyecto de la siguiente manera:

{ "presets": ["react-native", "react-native-dotenv"] }

Cree un archivo .env y agregue propiedades:

echo "SOMETHING=anything" > .env

Luego en su proyecto (JS):

import { SOMETHING } from ''react-native-dotenv'' console.log(SOMETHING) // "anything"



Paso 1: Cree un componente separado como este Nombre del componente: pagebase.js
Paso 2: dentro de este código de uso esto

export const BASE_URL = "http://192.168.10.10:4848/"; export const API_KEY = ''key_token'';

Paso 3: Úselo en cualquier componente, para usarlo primero importe este componente y luego úselo. Importarlo y usarlo:

import * as base from "./pagebase"; base.BASE_URL base.API_KEY


React native no tiene el concepto de variables globales. Aplica estrictamente el alcance modular , para promover la modularidad y la reutilización de los componentes.

A veces, sin embargo, necesita componentes para conocer su entorno. En este caso, es muy simple definir un módulo de Environment que los componentes pueden llamar para obtener variables de entorno, por ejemplo:

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

Esto crea un entorno singleton que se puede acceder desde cualquier lugar dentro del alcance de su aplicación. Debe require(...) explícitamente require(...) el módulo de cualquier componente que use variables de entorno, pero eso es algo bueno.


Utilicé el polyfill __DEV__ que está integrado en react-native para resolver este problema. Se establece automáticamente en true siempre que no esté creando reacción nativa para la producción.

P.ej:

//vars.js let url, publicKey; if (__DEV__) { url = ... publicKey = ... } else { url = ... publicKey = ... } export {url, publicKey}

Luego solo import {url} from ''../vars'' y siempre obtendrás el correcto. Desafortunadamente, esto no funcionará si desea más de dos entornos, pero es fácil y no implica agregar más dependencias a su proyecto.


Yo uso babel-plugin-transform-inline-environment-variables .

Lo que hice fue poner un archivo de configuración dentro de S3 con mis diferentes entornos.

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

CADA archivo env:

FIRSTENV=FIRSTVALUE SECONDENV=SECONDVALUE

Luego, agregué un nuevo script en mi package.json que ejecuta un script para agrupar

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

Dentro de su aplicación, probablemente tendrá un archivo de configuración que tiene:

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

que será reemplazado por babel para:

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

RECUERDE que debe usar process.env[''STRING''] NO process.env.STRING o no se convertirá correctamente.


también puede tener diferentes scripts env: production.env.sh development.env.sh production.env.sh

Y luego instálelos cuando comience a funcionar [que está vinculado a un alias] para que todo el archivo sh se exporte para cada variable env:

export SOME_VAR=1234 export SOME_OTHER=abc

Y luego agregar babel-plugin-transform-inline-environment-variables permitirá acceder a ellas en el código:

export const SOME_VAR: ?string = process.env.SOME_VAR; export const SOME_OTHER: ?string = process.env.SOME_OTHER;


[Source] Por lo que he encontrado, parece que, de forma predeterminada, solo es posible realizar configuraciones de producción y desarrollo (sin escenarios u otros entornos), ¿es así?

En este momento, he estado usando un archivo environment.js que se puede usar para detectar canales de lanzamiento de expo y cambiar las variables devueltas en función de eso, pero para compilar, necesito actualizar la variable que no es DEV devuelta para ser puesta en escena o pinchar:

import { Constants } from ''expo''; import { Platform } from ''react-native''; const localhost = Platform.OS === ''ios'' ? ''http://localhost:4000/'' : ''http://10.0.2.2:4000/''; const ENV = { dev: { apiUrl: localhost, }, staging: { apiUrl: ''https://your-staging-api-url-here.com/'' }, prod: { apiUrl: ''https://your-prod-api-url-here.com/'' }, } const getEnvVars = (env = Constants.manifest.releaseChannel) => { // What is __DEV__ ? // This variable is set to true when react-native is running in Dev mode. // __DEV__ is true when run locally, but false when published. if (__DEV__) { return ENV.dev; } else { // When publishing to production, change this to `ENV.prod` before running an `expo build` return ENV.staging; } } export default getEnvVars;

Alternativas

¿Alguien tiene experiencia con react-native-dotenv para proyectos creados con expo? Me encantaría escuchar tus pensamientos

react-native-dotenv