回答:
アプリの定数をハードコーディングして環境を切り替える(代わりにその方法を説明します)代わりに、ビルドプロセスでとを定義するという12要素の提案を使用することをお勧めしBASE_URL
ますAPI_KEY
。
環境をに公開する方法に答えるためにreact-native
、Babelのbabel-plugin-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)によってリアクションネイティブコードをトランスパイルする場合は、次のようなコードを作成するだけです。
const apiKey = process.env['API_KEY'];
そして、Babelは次のものに置き換えます。
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を使用することでした。次の.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"
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
または本番用のアプリを組み立てる場合(私の場合はAndroid):
cd android && ENVFILE=.env.production ./gradlew assembleRelease
Reactネイティブには、グローバル変数の概念がありません。これは、強制モジュラースコープを部品モジュール性と再利用性を促進するために、厳密に。
ただし、場合によっては、コンポーネントの環境を認識する必要があります。この場合、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__
この問題を解決するために、react-nativeに組み込まれているポリフィルを使用しました。true
本番用にネイティブのリアクションをビルドしていない限り、自動的にに設定されます。
例えば:
//vars.js
let url, publicKey;
if (__DEV__) {
url = ...
publicKey = ...
} else {
url = ...
publicKey = ...
}
export {url, publicKey}
それからちょうどimport {url} from '../vars'
あなたは常に正しいものを取得します。残念ながら、これは3つ以上の環境が必要な場合は機能しませんが、簡単で、プロジェクトに依存関係を追加する必要はありません。
環境変数の設定に使用される特定の方法は、CIサービス、ビルドアプローチ、プラットフォーム、および使用しているツールによって異なります。
CIでBuddybuildを使用してアプリを構築し、環境変数を管理していて、JSからconfigにアクセスする必要がある場合env.js.example
は、ソース管理にチェックインするためのwithキー(空の文字列値)を作成し、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
を実行するカスタムを作成しました。
私の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)
ステップ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.
ありがとう!これは私をつまずくものです!!!
[ソース]私が見つけたものから、それはデフォルトでのように見えます、それは本番および開発構成のみを実行することが可能です(ステージングまたは他の環境ではありません)–それは正しいですか?
現在、expoリリースチャネルを検出し、それに基づいて返される変数を変更するために使用できる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を使用した経験はありますか?私はあなたの考えを聞きたいです
別の環境スクリプトを使用することもできます。production.env.shdevelopment.env.sh production.env.sh
そして、作業を開始するときにそれらを調達します(エイリアスに関連付けられているだけです)ので、すべてのshファイルは各環境変数のエクスポートです
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が環境変数をサポートしていないため、私が採用したアプローチは、ネイティブモジュールを通じてビルド構成を公開することです。
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;
}
または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);