expoのapp.jsonでflavorみたいなことをやる

2 min read読了の目安(約1900字

expoのconfigはapp.jsonと並列してapp.config.jsを並べることで、動的なapp.jsonを構築できる。

// app.config.js

export default ({ config }) => { // app.jsonのexpo部分が取れる
  console.log(config.name)
  return config
}

ちなみにapp.jsonを削除した場合app.config.jsを読んでくれるので、こちらにすべての設定を記述することも可能だが、react-native-versionなどエコシステムが使えなくなったりしがちなので、app.jsonを残しつつ利用するのが良いだろう

flavorっぽいことをしてみる

これを利用してビルドflavorみたいなことをしてみよう。

元のapp.jsonがこのような状態と想定する

{
  "expo": {
    "name": "example-flavor-config",
    "slug": "example-flavor-config",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      }
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

そこに上書きした差分だけを記述したapp.staging.jsonをこんな感じで準備してみる

{
  "expo": {
    "name": "(staging)example-flavor-config",
    "slug": "example-flavor-config-staging",
    "splash": {
      "backgroundColor": "#000000"
    }
  }
}

JavaScriptでのobjectのマージは面倒なので、今回はdeepmergeを利用する

$ yarn add -D deepmerge

これであとはjsonを結合すれば良い

// app.config.js
import merge from "deepmerge"
import stagingConfig from "./app.staging.json"

export default ({ config }) => {
  if (process.env.BUILD_FLAVOR === "staging") {
    return merge(config, stagingConfig.expo)
  }
  return config
}

あとはこんな感じで環境変数を差し替えることで使えるようになる

$ BUILD_FLAVOR=staging expo build:ios