実践 React Native 運用チェックシート

この記事は[React Native Advent Calendar 2020](https://qiita.com/advent-calendar/2020/react-native)の1日目の記事です。

[実践 React Native 設計チェックシート](https://qiita.com/shoken/items/8d41312fd826da40ce7e) 続編の運用編として書きます。

キッチハイクのアプリはReact Nativeで開発を始め、4年目に入りました。これまでのプロダクション運用で、7回のReact Nativeアップグレードと100回以上のリリースを行いました。他にも運用で得た知見・ノウハウをまとめたいと思います。

これからReact Native をプロダクションリリースする方、すでに運用中の方に読んでいただければ嬉しいです。これから導入したいライブラリや仕組みも多く、まだまだ運用は楽になると思っています。


# 2020年に公開されたReact Native開発・運用ストーリー

2020年は複数社のReact Native開発・運用ストーリーが公開された年になりました。その中でもこれから紹介するShopify, Khan Academy, Wixは多くのユーザーに使われており、大規模アプリのReact Native開発・運用ストーリーとその知見を知ることができます。

## Shopify

Shopifyは自社のテックブログで、[React Native is the Future of Mobile at Shopify](https://shopify.engineering/react-native-future-mobile-shopify) を2020年1月29日に公開し、React Nativeへの期待を記事にしました。またQiitaには、Shopifyから2020年4月15日に配信されたpodcast、ShopifyのVP Engineeringのインタビューセッションについて書かれた記事があり、 [RNを辞めたAirbnb、RNを採択したShopify](https://qiita.com/taneba/items/9903064aaaffdf041022#rn%E3%82%92%E8%BE%9E%E3%82%81%E3%81%9Fairbnbrn%E3%82%92%E6%8E%A1%E6%8A%9E%E3%81%97%E3%81%9Fshopify) の部分は多くのReact Nativeエンジニアが知りたいことではないかと思います。

## Khan Academy

2020年9月1日、InfoQに [Khan AcademyのReact Nativeへの移行のメリットとデメリット](https://www.infoq.com/jp/news/2020/09/khan-academy-react-native-apps/) が掲載されました。この記事は、Khan Academyのテックブログに投稿された [Our Transition to React Native](https://blog.khanacademy.org/our-transition-to-react-native/) をもとに、2年間にわたる移行がまとめられています。既存のネイティブアプリをReact Nativeで再実装する過程での段階的なステップが書かれており、移行がスムーズに行われたものではなく困難な箇所もあったことがわかります。

## Wix

Wixは自社アプリをReact Nativeで開発しつつ、E2Eテストライブラリ [Detox](https://github.com/wix/Detox) や ナビゲーションライブラリ [React Native Navigation](https://github.com/wix/react-native-navigation) など、多くのライブラリを公開しています。
テックブログで2020年11月10日にスタートした[React Native At Wix](https://medium.com/wix-engineering/react-native-at-wix-d56c3745aaff)を紹介します。この記事はWixでの5年間のReact Native開発をコミュニティに共有する目的で書かれており、8パートからなる長編が予定されています。現在はまだ第2パートまでしか公開されていませんが、すでに大人数チームでの開発を効率化するための自社フレームワーク開発というディープなものになっており、続きが楽しみです。

## リクルート

日本の会社では2020年03月31日の記事で[リクルートがB2Bのスマホアプリ開発でReact Nativeを採用した理由](https://www.atmarkit.co.jp/ait/articles/2003/31/news004.html)が@ITに掲載されています。

# React Native アプリ運用のポイント

4年間の運用で大切だと感じたのは、React, React Nativeの最新情報キャッチアップ力です。React Nativeは開発途中にあり、コアアーキテクチャレベルで変更が行われています。各バージョンのBreaking changesやDeprecatedの情報をキャッチアップすることで、React Nativeの進化についていくことが可能で、最新のアーキテクチャによる恩恵を受けることができます。逆に、少し目を離すとアップグレードが困難になります。冒頭に紹介した他社が公開している事例や開発ストーリーも貴重な情報源となります。公開に感謝しつつ参考にし、こちらも公開できる知見は積極的に公開するような取り組みで、React Nativeの大きなエコシステムが回ることに少しでも貢献できればと考えています。

まずは、React Native本体のアップグレードについてです。運用チェックシートの最初のポイントは、定期的にReact Nativeアップグレードする体制と工数があるか、という点です。

# 過去7回のReact Native アップグレード

キッチハイクは4年間で7回のアップグレードを行ってきました。

バージョン|開始時期|マージ|期間|コメント
----|----|----|----|----
0.42.3 | 2017/06/30 | -- | -- | 開発開始
-> 0.46.2 | 2017/08/09 | -- | -- | アプリ公開バージョン
-> 0.50.4 | 2017/11/24 | 2018/01/17 | 約2ヶ月 | 大変だった
-> 0.53.3 | 2018/04/11 | 2018/04/18 | 1週間 | あっさり
-> 0.56.1 | 2018/10/18 | 2018/10/31 | 2週間 | 
-> 0.59.6 | 2019/06/10 | 2019/07/10 | 1ヶ月 | Android 64bit対応
-> 0.59.10 | 2019/11/07 | 2019/11/15 | 1週間 | マイナーアップデート 
-> 0.62.2 | 2020/05/11 | 2020/05/27 | 2週間 | AndroidX対応

アプリをストアに公開後、半年に1回のペースでアップグレードを行ってきました。短いものだと1週間、長くて約2ヶ月かかってます。

## 0.46.2 -> 0.50.4 の思い出

初めてのアップグレードだったのでとにかく大変だった印象です。11月から着手して、クリスマスがすぎ、大晦日がすぎ、正月がすぎてもなかなかエラーが解消せず、先が見えない不安がありました。今でも覚えているのが、AIRMap(いまはreact-native-maps)とfbsdkです。AIRMapはAirbnbが開発していたライブラリでその名の通り地図表示なのですが、ネイティブ層のビルドエラーで苦しんだ記憶があります。かなりObjective-Cのソースコードを読みました。のちのAirbnbのReact Nativeやめる宣言により、ライブラリ開発がどうなるか心配だったのですが無事にReact Native Communityに移管されてメンテナンスされてます。ありがたし。

もう一つのfbsdkはFacebookログインに必要なライブラリなのですが、React Nativeと開発元が同じなのになぜこうもエラーになるのか、と。結局、fbsdkの最新バージョンでのビルドはあきらめて、一つ戻したバージョンにしたと思います。

キッチハイクはWebエンジニアがReact Nativeでアプリ開発を始めたので、ネイティブに慣れてなかったこともあり、XcodeやAndroid Studioのビルドエラーの解決に時間がかかりましたが、いまとなってはここでチームに知見を貯めれたことが、この後数回行われるアップグレードに良い影響を与えていると思います。

## 0.50.4 -> 0.53.3の思い出

前回2ヶ月かかったので、そのくらいかかるのかなとのぞんだところ、結果的には1週間で終わったのがこのアップグレードです。しかし、またreact-native-mapsでエラーが。エラーというか、Androidだけ地図が表示されないというものでした。前回と今回の結果で、mapsライブラリはアップグレード時の最重要リスト入りします。この後のアップグレードでも地図まわりは特に慎重に確認することになりました。

前回の経験と、React Native本体のBreaking changesが少なかったことから、いくつかエラーは出たものの簡単な修正で解決できるものでした。react-native-maps以外は。

## 0.53.3 -> 0.56.1の思い出

この回からPod, Gradleも含めて各ライブラリもできるだけ最新に追従しようと試みます。今回はmapsのエラーこそなかったものの、各ライブラリをアップデートしたことによるスタイル崩れが発生し、時間を費やすことになります。また、この期間にReact Nativeを開発していたら覚えている方も多いと思われる、日本語キーボードの変換問題（CJK問題）にも遭遇します。

前回よりも時間がかかりましたが、2週間でアップグレードが終わりました。

# React Native本体以外のライブラリ

キッチハイクではReact Native以外のライブラリを、ユーザー影響・影響範囲の2軸で分類し、バージョンアップの方針を決めています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/7b7e5f99-0d03-8f94-6f99-82cc914127f0.png)


その中でもユーザー影響大・影響範囲広に位置する5つのライブラリを主要ライブラリとしています。

- react-navigation
- react-native-firebase
- react-native-push-notification
- expo-secure-store
- @react-native-community/async-storage


## 主要ライブラリのアップグレード

主要ライブラリのようにユーザー影響が大きく・影響範囲が広いものは、個別プロジェクトとしてアップグレードを行っています。
特に `react-navigation` と `react-native-firebase` の2つは大きな変更が入ることが多く、情報のキャッチアップを行っています。

### React Navigation

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/15047b2f-434c-ce03-0c0b-f165ac9d6993.png)


v3からv4になる時に、stack, tabs, drawerにパッケージ分離が行われました。
またv4からv5でAPIの刷新が行われ、互換性がなくなりました。

現在v6が開発中で、ロードマップがissueとして公開されています。
[Roadmap for v6 · Issue \#8981 · react\-navigation/react\-navigation](https://github.com/react-navigation/react-navigation/issues/8981)

キッチハイクではv4を使っており、タイミングをみてv5に移行したいと考えています。

### React Native Firebase

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/51a8298a-3020-bda9-c202-01a8080c3e63.png)


v5からv6になるときにアーキテクチャが変更され、各モジュールで細かく分割されました。自社で必要な個別モジュールのみに差し替え作業を行いました。

キッチハイクでは以下のモジュールを使用しています。

- @react-native-firebase/app
- @react-native-firebase/analytics
- @react-native-firebase/dynamic-links
- @react-native-firebase/messaging
- @react-native-firebase/remote-config



# リリース運用

日々リリースしていくなかで考慮が必要な点をピックアップします。

## Apple / Google ベンダー対応

React Nativeアプリを運用していく中でもベンター対応は必須になってきます。こちらもReact Nativeと同じくキャッチアップが重要になります。App Store ConnectやGoogle Play Consoleに目立つように表示されるものもあれば、メールで送信されるものもあります。

ベンダー対応は期限が決まっているので、計画的に対応する必要があります。例えば、Android 64bit対応は2019年8月1日までという風に、以下のようにアナウンスされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/7a2a7ede-9004-d76a-1c5f-0c47087bb6ef.png)


いくつかはReact Naitve本体のアップグレードで対応できるものもありますが、個別に対応するものもあります。これまでに対応したもので、印象に残っているものを事例として以下のものがありました。

### iOS

iOS 13

- Sign in with Apple
- Launch Storyboard
- ダークモード
- UIWebView廃止

iOS 14

- IDFA許可取得対応。参考記事 [iOS14からIDFA取得がオプトイン形式になる理由と今後予想される動き \- Qiita](https://qiita.com/tamago3keran/items/17bcd7b51cdcd1b03837)
- Xcode 12 対応

### Android

- 64bit対応 (React Native 0.59.x でサポート)
- AndroidX への移行（React Native 0.60.x でサポート）
- [Google Playの対象APIレベル要件](https://developer.android.com/distribute/best-practices/develop/target-sdk?hl=ja)への対応（targetSdkVersion）

## クラッシュレポート

長期的に安定したアプリを提供するため、クラッシュレポートの運用が必要になります。
React Nativeはネイティブアプリとは違い、各アプリベンダーが提供しているクラッシュレポートではJavaScriptレイヤーのエラー情報を得ることができません。

そこでJavaScriptレイヤーのエラー情報を得るためにライブラリを導入する必要があります。
代表的なものは以下のものです。

- [Sentry](https://sentry.io/welcome/)
- [Firebase Crashlytics](https://firebase.google.com/docs/crashlytics?hl=ja)
- [Amplitude](https://amplitude.com/)
- [Bugsnag](https://www.bugsnag.com/platforms/react-native-error-reporting)

キッチハイクではSentryを使っています。

## アプリサイズ

リリースを重ねるごとにアプリサイズは大きくなっていきます。キッチハイクアプリはフォントを入れた時にサイズが大きく増えてしまいました。サイズが約100MB程度になっており、Wifiに接続していない屋外でのインストール・アップデートに時間がかかってしまうので、アプリのサイズは少しでも減らしたいところです。

Androidアプリについては比較的簡単にアナライズして、アプリサイズを減らすことにトライできます。弊社のテックブログに記事がありますので、参考にしてもらえればと思います。

[React Nativeアプリのサイズを35%減らした話 Android編 \- KitchHike Tech Blog](https://tech.kitchhike.com/entry/reduce-react-native-app-size)


# セキュリティ対策

アプリをプロダクション運用する際にセキュリティに関する対策も必要不可欠になってきます。
React Native公式ドキュメントにも[Security](https://reactnative.dev/docs/security)のページがあり、以下の3つの観点が書かれています。

- ストレージ（Async Storage, Secure Storage)
- 認証とDeep Link（OAuth2とリダイレクト）
- ネットワークセキュリティ（SSL Pinning）

キッチハイクではSecure Storageの対応を行いました。ライブラリはUnimodule化された[expo\-secure\-store](https://www.npmjs.com/package/expo-secure-store)を使っています。UnimoduleでExpoのライブラリを使えるのは便利です。


# マーケティング運用

サービスを成長させていくなかで、デジタル広告戦略でアプリのインストールを増やしたい場合、広告トラッキングが必要になります。React Nativeアプリと連携できる代表的なアトリビューションプロバイダーは以下となります。

- [AppsFlyer](https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin)
- [Adjust](https://github.com/adjust/react_native_sdk)

キッチハイクではAppsFlyerとGoogle Analyticsを連携させて、BigQueryで分析しています。（現在は戦略上広告ストップしています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/6773fbc5-a090-5e79-438b-2612c87380bc.png)

以前、React Nativeアプリの広告計測事例で発表した資料を貼っておきます。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32750/e3b3df5b-e72c-c38a-3c30-aec450f42cdf.png)](https://speakerdeck.com/shoken/react-native-with-appsflyer-and-firebase-analytics)

https://speakerdeck.com/shoken/react-native-with-appsflyer-and-firebase-analytics

# おまけ : RN Featuresについて

ここからは弊社テックブログの宣伝になります。
React Nativeアプリのプロダクション運用では、情報のキャッチアップが重要になることが実際に運用して感じたことです。そこで弊社では毎月1回、React Native関連の情報を有志が持ち寄ったものをまとめて、テックブログに公開する[RN Features](https://tech.kitchhike.com/archive/category/RNFeatures)という活動を続けています。

直近のエントリーはこのようなものです。

- [RN Features 2020年11月号 \- React Navigation v6 ロードマップ, Wix の連載記事, Swift とのパフォーマンス比較 \- KitchHike Tech Blog](https://tech.kitchhike.com/entry/react-native-features-202011)
- [RN Features 2020年10月号 \- React v17\.0 リリース, Node\.js v15 リリース, リクルートの開発事例, 第5回 React Native Tech Blog LT \- KitchHike Tech Blog](https://tech.kitchhike.com/entry/react-native-features-202010)
- [RN Features 2020年9月増刊号 \- React Native パフォーマンス最適化, Hooks 導入事例, React Native Game Engine \- KitchHike Tech Blog](https://tech.kitchhike.com/entry/react-native-features-202009-extra)

これからも毎月1回、キャッチアップしたReact Nativeの情報を公開していきますので、興味がある方はぜひ購読してもらえればと思います。

----------------------------------------------

最後まで読んでいただいてありがとうございました。

2日目は @nekoniki さんです。お願いします！