基本的に React Native は development か production かしか切り替えができない。
__DEV__
React Native では development かどうかを判別する仕組みとして __DEV__
というグローバルな変数が定義されている。次のページに書いてあるように、 packager に bundle してもらう際、 dev という query prameter に true
か 1
を指定したときに __DEV__ = true
としてくれる。
これを見て設定を切り替えればいい。
ちなみに Android で cd android && ./gradlew assembleRelease
したり iOS で Release ビルドした場合はきちんと __DEV__ === false
にしてくれる。
react-native-config
と、ここまではいいんだけど staging と production をわけたいとなると本体の仕組みだけでは無理になる。
There are no staging vs. production options in the packager. You'll have to determine that at runtime.
react-native-config はここらへんをうまいこと切り分けてくれるパッケージ。
仕組みとしてはビルド時に環境を指定して設定値を native app に埋め込み、実行時にそれを bridge して読み込めるようにする、というもの。
README がとても丁寧に書かれているのでそれを読めばいいんだけど、備忘録代わりに設定方法をひととおり書いておく。
react-native-config は .env
というファイルをデフォルトの設定ファイルとして読み込んでくれる。中身は sh 変数の定義のように VAR=VALUE
という形で設定値を定義していく。
まず環境と設定ファイルを次のように作っておく。
環境 | ファイル名 |
---|---|
development | .env |
staging | .env.staging |
production | .env.production |
API_ENDPOINT=http://dev.example.com/api/
API_ENDPOINT=http://stg.example.com/api/
API_ENDPOINT=http://prd.example.com/api/
Android
Android の場合、 ENVFILE
という環境変数を指定しながら react-native run-android
するだけ。 staging 環境のアプリをビルドしたい場合、次で OK 。
ENVFILE=.env.staging react-native run-android
iOS
iOS の場合それぞれの環境ごとに scheme を作る必要がある。
- アプリ名と同じ名前の scheme ができているはずなのでそれを duplicate
- 名前はわかりやすく
appname-staging
とかにしておく
- 名前はわかりやすく
- duplicate した scheme の Build -> Pre-actions に
echo ".env.staging" > /tmp/envfile
という内容の sh script を書く
↑を .env
含めてすべての設定ファイルに対してやる。 /tmp/envfile
というグローバルな状態見てるから毎回書き換えないと前回の状態を引き継いじゃうので。
これで OK 。
使い分け
development かどうかわかればいいという場合は __DEV__
での切り替えで、それ以上に環境を細かくわけたい場合は react-native-config を使えばいい。
mocha と react-native-config
mocha でテストを書く場合、 native app は経由しないというかできない、つまり react-native-config を使おうとすると当然のごとく設定値を読み込めなくて落ちるんだけど、それを何とかする package を @shinout が作ってくれた。
ここらへんの解説もしたいけど、テストについてを含めて今度まとめて書く予定。