【ReactNative】単一ソースを複数アプリ(target)にビルドしたときの話
背景
同じようなシステムを別のターゲットに少しだけ内容を変えてリリースしたいという状況だった。 具体的には、国家試験対策アプリを歯科医師用と歯科衛生士用に出したかった。 歯科医師用アプリはiOS, Androidでリリース済みで、衛生士用も同じく両プラットフォームで出したかった。 システムはほぼ同じで、コンテンツ(クイズの内容・カテゴリ)と少しのUI、iconなどだけ変えて別アプリとして出したかった。
検討したこと
1. xcodeでtargetを2つ作る 2. 共通部分をnpm pacakge化 3. 【採用した】共通部分をgit submodule化
採用しなかったやつとその理由
1. xcodeでtargetを2つ作る
これが一番スマートだと思って、一度はやってみた。しかし、
- iOS, Android両方でビルドを分けるのは思ったより大変だった - targetによって切り分ける処理はネイティブコードでしかできない(僕調べ)ので、環境変数 などで切り分けるしかなくてメリットが小さかった - ※1 ReactNative特有の原因により、解決困難なエラーが出まくった - だだでさえ不確定要素の多いReactNativeで、nativeでもあまりやらないことをすると危険
swiftとかで書かれたアプリなら、この方法(複数targetを作る)が良いんだと思う。この方法はネット上に意外と多く転がっているので、swiftなら時間かけずにできそう。
※1 ReactNative特有の原因により、解決困難なエラーが出まくった => 詳しくは割愛する(後日書くかも)が、ReactNativeの実装上、複数targetにビルドするのは想定されていない気がしている。
2. 共通部分をnpm pacakge化
2と3は似ているが、submoduleによる管理・共通化の方が運用が楽そうだった。(後述)
あと単純に、npm pacakgeに詳しい人
よりもgitに詳しい人
の方が世の中に多そうなので引き継いだ人が楽になる可能性が高いと判断した。
【採用した】共通部分をgit submodule化
git submodule
については詳しく触れないが、使いどころさえミスらなければ非常に便利だと思うので知っておくと良いと思う。
今回のプロジェクトはこんなディレクトリ構成になっていて、基本的な実装部分はsrc
以下にまとめた。
そして、今回submodule化したのはsrc
以下の全て。
画像を見ればわかるように、redux関連の処理と各スクリーン・コンポーネント、ナビゲーション設定系も全てまとめている。
submoduleを使ったメリットは沢山あるしsubmoduleについて調べれば分かりやすいと思うので割愛するが、大きなデメリットが1つあるので紹介する。それは依存ライブラリのリンク(Linking Libraries)
をプロジェクトごとにしなければならないことだ。(Linking Librariesについては「参考」のリンク参照)
NativeがいじれないからReactNaitveを選定したのに結局触らなアカンのかい!って気持ちになるのをプロジェクトごとにやるのか。。って気持ちになるが、意外と2回目の作業は詰まらずいけた。むしろ復習になってすごく理解が進んだ。なのでこれについては実はあまりデメリットに感じていない。 ただ、複数人でプロジェクトを回す場合はやはり大きなデメリットになるかも。
追記
BuildSettings (iOS), BuildVariant (Android)を使うとプラットフォーム側でビルド時に処理してくれるらしい。 speakerdeck.com