답변:
대신 앱 상수를 하드 코딩 및 환경에 스위치를하는, 내가 사용하는 것이 좋습니다 (나는 순간에 그 작업을 수행하는 방법을 설명 할 것이다) 열두 요소의 빌드 프로세스를 갖는 제안을 당신의 정의 BASE_URL
와를 API_KEY
.
환경을 노출시키는 방법에 대답하려면 react-native
Babel의 babel-plugin-transform-inline-environment-variables를 사용하는 것이 좋습니다 .
이 작업을 수행하려면 플러그인을 다운로드 한 다음 a를 설정 .babelrc
해야하며 다음과 같이 표시되어야합니다.
{
"presets": ["react-native"],
"plugins": [
"transform-inline-environment-variables"
]
}
따라서 실행 API_KEY=my-app-id react-native bundle
(또는 start, run-ios 또는 run-android)을 실행 하여 반응 네이티브 코드를 변환 하면 코드를 다음과 같이하면됩니다.
const apiKey = process.env['API_KEY'];
그리고 바벨은 이것을 다음으로 대체 할 것입니다.
const apiKey = 'my-app-id';
도움이 되었기를 바랍니다!
process.env
입니다 NODE_ENV
.
process.env.API_KEY
... process.env['API_KEY']
대신 변수를 사용할 수 없습니다 ... 대신 사용하십시오
react-native start --reset-cache
환경 변수를 변경할 때마다 실행 하여 번 들러의 캐시를 지워야 합니다.
내가 찾은 가장 간단한 ( 최상의 또는 이상적이지 않은 ) 솔루션은 react-native-dotenv 를 사용하는 것 입니다. "react-native-dotenv"사전 설정을 .babelrc
프로젝트 루트 의 파일에 다음과 같이 추가하면됩니다.
{
"presets": ["react-native", "react-native-dotenv"]
}
.env
파일을 작성하고 특성을 추가하십시오.
echo "SOMETHING=anything" > .env
그런 다음 프로젝트 (JS)에서 :
import { SOMETHING } from 'react-native-dotenv'
console.log(SOMETHING) // "anything"
base_url
모두 staging
와 production
?
.env
환경에 따라 다른 파일을 사용 하거나 다른 파일 에서 일부 값을 재사용하는 것에 대해 질문 .env
하고 있으므로 스테이징 및 프로덕션과 같이 파일을 복제하지 않습니까?
.env
환경에 따라 파일하자의 말 staging
과 production
.
제 생각에는 가장 좋은 옵션은 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
그런 다음 사용하십시오.
import Config from 'react-native-config'
Config.API_URL // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY // 'abcdefgh'
다른 환경을 사용하려면 기본적으로 다음과 같이 ENVFILE 변수를 설정하십시오.
ENVFILE=.env.staging react-native run-android
또는 프로덕션 용 앱 조립 (내 경우에는 안드로이드) :
cd android && ENVFILE=.env.production ./gradlew assembleRelease
반응 네이티브에는 전역 변수라는 개념이 없습니다. 컴포넌트 모듈 성과 재사용 성을 높이기 위해 모듈 식 범위를 엄격하게 적용 합니다.
그러나 때로는 환경을 인식하기 위해 구성 요소가 필요합니다. 이 경우 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
my-component.js
var Environment = require('./environment.js')
...somewhere in your code...
var url = Environment.BASE_URL
이렇게하면 앱 범위 내 어디에서나 액세스 할 수 있는 싱글 톤 환경 이 만들어집니다 . require(...)
환경 변수를 사용하는 모든 구성 요소에서 모듈 을 명시 적으로 지정 해야하지만 좋은 것입니다.
getPlatform()
입니다. 나는이 같은 파일을 가지고 있지만 여기에 논리를 완료 원주민 반응하지 수
staging
또는 production
사용자 환경에 따라 때문에, 심지어 평균을. 예를 들어, IOS와 Android에 대해 다른 특징을 원할 경우 환경 index.ios.js
과 index.android.js
파일 을 가져 와서 플랫폼을 설정하여 환경을 초기화 할 수 있습니다 ( 예 :) Environment.initialize('android')
.
env.js
파일 을 작성하는 경우 체크인에서 저장소 로 파일을 무시하고 비어있는 문자열 값과 함께 사용 된 키를 env.js.example
체크인하는 다른 파일 로 복사하여 다른 사용자가 앱을 더 쉽게 빌드 할 수 있도록하십시오. 실수로 프로젝트 시크릿을 체크인 하는 경우 소스에서뿐만 아니라 히스토리에서도 제거하기 위해 히스토리 를 다시 작성 하는 것이 좋습니다.
__DEV__
이 문제를 해결하기 위해 반응 네이티브에 내장 된 폴리 필을 사용했습니다 . true
프로덕션 용 기본 반응을 작성하지 않는 한 자동으로 설정됩니다 .
예 :
//vars.js
let url, publicKey;
if (__DEV__) {
url = ...
publicKey = ...
} else {
url = ...
publicKey = ...
}
export {url, publicKey}
그런 다음 import {url} from '../vars'
항상 올바른 것을 얻을 수 있습니다. 불행히도, 둘 이상의 환경을 원할 경우 작동하지 않지만 쉽고 간단하며 프로젝트에 더 많은 종속성을 추가하지 않습니다.
환경 변수를 설정하는 데 사용되는 특정 방법은 사용중인 CI 서비스, 빌드 방식, 플랫폼 및 도구에 따라 다릅니다.
CI 용 Buddybuild를 사용하여 앱을 빌드 하고 환경 변수를 관리 하고 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
팁 : 개발 과정에서 실수로 구성 및 비밀이 소스 제어에 체크인되지 않도록 추가 env.js
하는 것을 잊지 마십시오 .gitignore
.
그런 다음와 같은 Buddybuild 변수를 사용하여 파일을 작성하는 방법을 관리하여 BUDDYBUILD_VARIANTS
빌드시 구성이 생성되는 방식을보다 효과적으로 제어 할 수 있습니다.
env.js.example
부품 은 어떻게 작동합니까? 로컬 환경에서 앱을 시작하고 싶다고 가정 해 봅시다. 내 경우 env.js
파일이 gitignore에 있고 env.js.example
아웃 라인으로 사용하는 경우,이 env.js.example
난 그냥 조금이 부분에 의해 무엇을 의미하는지에 혼란 스러워요, 그래서 합법적 인 JS 확장되지 않습니다
env.js.example
파일은 코드베이스에 참조 문서로서, 앱이 어떤 구성 키를 사용하고자 하는가에 대한 정식 소스입니다. 앱을 실행하는 데 필요한 키와 한 번 복사하고 이름을 바꾼 파일 이름을 설명합니다. 패턴은 패턴을 들어 올린 dotenv gem을 사용하는 Ruby 앱에서 일반적입니다 .
나는 다음과 같은 라이브러리가 퍼즐의 누락 된 비트 인 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를 지원하기위한 풀 요청이 있습니다. 그것도 확인하십시오.
다른 환경에 대해 다른 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 run scripts
을 실행 하는 사용자 지정 을 만들었습니다 .
내 패키지 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)
1 단계 :이 컴포넌트 이름과 같은 별도의 컴포넌트 작성 : pagebase.js
2 단계 :이 사용 코드 내에서
export const BASE_URL = "http://192.168.10.10:4848/";
export const API_KEY = 'key_token';
3 단계 : 모든 구성 요소에서 사용하십시오. 먼저이 구성 요소를 가져온 후 사용하십시오. 가져 와서 사용하십시오.
import * as base from "./pagebase";
base.BASE_URL
base.API_KEY
나는 사용한다 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
그런 다음 package.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']
다음과 같이 babel로 대체됩니다.
const FIRSTENV = 'FIRSTVALUE'
const SECONDENV = 'SECONDVALUE'
process.env['STRING']
NOT 을 사용해야 process.env.STRING
합니다. 그렇지 않으면 제대로 변환되지 않습니다.
REMEMBER you have to use process.env['STRING'] NOT process.env.STRING or it won't convert properly.
감사! 이것은 나를 여행하는 사람이다! !!
[출처] 내가 찾은 것으로부터, 기본적으로 보이는 것처럼, 프로덕션 및 개발 구성 만 할 수 있습니다 (스테이징 또는 기타 환경 없음) – 맞습니까?
지금은 엑스포 릴리스 채널을 감지하고 그에 따라 반환 된 변수를 변경하는 데 사용할 수있는 environment.js 파일을 사용하고 있지만 빌드 를 위해 준비되지 않은 DEV 변수 를 업데이트해야합니다. 찌르다:
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;
대안
누구나 엑스포로 빌드 된 프로젝트에 react-native-dotenv 사용 경험이 있습니까? 당신의 생각을 듣고 싶습니다
다른 env 스크립트를 가질 수도 있습니다 : production.env.sh development.env.sh production.env.sh
그런 다음 작업을 시작할 때 (별명에 묶여있는) 소스를 가져 와서 모든 sh 파일이 각 env 변수에 대해 내보내집니다.
export SOME_VAR=1234
export SOME_OTHER=abc
그런 다음 babel-plugin-transform-inline-environment-variables를 추가하면 코드에서 해당 변수에 액세스 할 수 있습니다.
export const SOME_VAR: ?string = process.env.SOME_VAR;
export const SOME_OTHER: ?string = process.env.SOME_OTHER;
@chapinkapa의 답변이 좋습니다. Mobile Center가 환경 변수를 지원하지 않기 때문에 취한 접근법은 기본 모듈을 통해 빌드 구성을 노출하는 것입니다.
안드로이드에서 :
@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;
}
또는 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]
}
빌드 구성을 동기식으로 읽고 Javascript에서 동작 방식을 결정할 수 있습니다.
process.env.blabla
대신에 변수에 액세스 할 수 있습니다 process.env['blabla']
. 나는 최근에 그것을 작동시키고 GitHub의 문제에서 어떻게했는지에 대해 논평했습니다. 허용 된 답변을 기반으로 캐시에 문제가 있었기 때문입니다. 여기 에 문제가 있습니다.
최신 RN 버전의 경우 다음 기본 모듈을 사용할 수 있습니다. https://github.com/luggit/react-native-config
import {Platform} from 'react-native';
console.log(Platform);