開発中、環境によって API のエンドポイントの向き先や設定を変更して動作チェックしたい、ということがよくある。
しかしながら、ReactNative では、process.env に渡されるのが基本 process.env.NODE_ENV だけで、かつ内部で development か production に書き換えているため、適当な環境変数を外部から渡して挙動を変えることが、development or production しか行えない。
そのためのアプローチの一つとして react-native-config があり、それについての詳細は以下に解りやすくまとまっている。
ただ、react-native-config では、あくまでネイティブ側に埋め込み、JS 側ではブリッジ経由で取得というアプローチを取っているため
- アプリのビルド時にターゲット(stagingとか)変更
- 定数を変えたらアプリの再コンパイルが必要
が必要となる。また ReactNative のテスト環境は、基本的に実機やシュミレータを使わずにテストを実行するため、テスト用にうまく動く設定が必要となる。
-
https://github.com/CureApp/react-native-config-node
- ↑を jest で利用するために babel でテスト時に書き換える設定
- https://gist.github.com/alanshaw/5002182652163a1c8c3a8ed2c25eee1d
react-native-dotenv を使う
別のアプローチとして、babel でソースコード自体を書き換えてしまい動かす、react-native-dotenv というライブラリがある。
これを入れ、babel の設定を書くことで、.env に記述した定数を
import { API_URL } from 'react-native-dotenv'
のように記載することが出来る。.env.production を用意すると、リリースビルド時に適用される。また JS 側だけで使えるため、テスト時にも問題無く利用することが出来る。
ただ、.env の定数を書き換えただけでは反映されず、利用箇所すべての .js ファイルのタイムスタンプを更新して babel がトランスパイルすることを待つか、Config.js 的なファイルを一つ用意して、こいつが import && export をすることで修正ファイルを一箇所に集約する
// Config.js。このファイルだけ .env を書き換えたら更新する。びみょう…
import { API_URL } from 'react-native-dotenv'
export { API_URL }
か、
$ rm -rf $TMPDIR/react-*
$ yarn start
のように一度キャッシュファイルを削除してから、再度起動する必要がある。なおキャッシュファイルを消して再度起動すると、ロードに非常に時間がかかるため、react-native-config でアプリをビルドし直した方がむしろ早い環境もある。
また、ネイティブ側からの定数の取得はもちろんできない。
react-native-config とどちらを使うべきか
単純に比較すると react-native-config と比べても一長一短あるため、どちらが良いかはプロジェクトによると思うが、とりあえず始めるに当たり少ない設定で react-native-dotenv で使うことができるので、まず使ってみるのも良いと思う。
なお ci では cp .env.ci .env
みたいに CI 用の環境を .env とすることで、設定を切り分けて動かしている。