背景
React Native (0.30.0) では、
(node_modules/react-native/)Libraries/JavaScriptAppEngine/InitializeJavaScriptAppEngine.js
に
function setUpProcess(): void {
global.process = global.process || {};
global.process.env = global.process.env || {};
if (!global.process.env.NODE_ENV) {
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
}
}
という実装がされているが、local-cli/cliEntry.js の中を追っていくと ReactNative側(クライアント側)には process は渡されていないため、 process はここで必ず初期化が行われていることが分かる。
そのため、
$ NODE_ENV=staging react-native start
などとしても、 例えば index.ios.jsで
console.log(process.env.NODE_ENV) //=> development
になってしまう。
手法
これを望む挙動にするには、プロジェクトのルートに .babelrc を作成し、
{
"presets": ["react-native"],
"plugins": [
"babel-remove-process-env-assignment",
"babel-plugin-transform-inline-environment-variables"
]
}
として、
$ npm i -D babel-remove-process-env-assignment
$ npm i -D babel-plugin-transform-inline-environment-variables
で依存関係をインストールしておく。
(ちなみに、 npmのページにも、Babel plugin to remove assignments to process.env, to work around a long-standing react-native bugと書かれている。)
すると、NODE_ENV=staging react-native start によって、きちんと staging が得られることが確認できる。
※ ここで、 react-nativeコマンドは、 node node_modules/local-cli/cli.jsへのエイリアスなので、
$ NODE_ENV=staging node node_modules/local-cli/cli.js start
と記述してもよい。
ただし、ここから NODE_ENV を変えてもう一度 start したい場合は、cacheをクリアする必要があるので、
$ NODE_ENV=development node node_modules/local-cli/cli.js start --reset-cache
と、 --reset-cache オプションを付けなくてはならない。
この辺の処理を例えば
# !/bin/sh
NODE_ENV=development node node_modules/react-native/local-cli/cli.js start "$@"
# !/bin/sh
NODE_ENV=staging node node_modules/react-native/local-cli/cli.js start "$@"
"scripts": {
"start": "./script/development.sh",
"start:dev": "./script/development.sh",
"start:dev:reset": "./script/development.sh --reset-cache",
"stat:staging:reset": "./script/staging.sh --reset-cache",
}
などとまとめておけば、
$ npm run start:dev
とすることで、いつでも正しい NODE_ENV の値を得ることができる。