207 Tech Blog

テクノロジーで物流を変える 207 (ニーマルナナ) 株式会社のテックブログ

令和4年最新版!207流React Nativeアプリの運用術

207株式会社でソフトウェアエンジニアをしている id:ryo-rm です。

1年前、EAS Buildを使ったリリースフローについて書きました。
今回は1年経ってリリースフローがどう変わったのか、EASをどう活用しているか、React Nativeアプリをどう運用しているか等について書こうと思います。
現在もexpo-updatesによるOTAアップデートを活用しており、高速なデプロイを実現しています。

tech.207-inc.com

アプリケーションの特性についてと、207の開発組織について

TODOCUサポーター という、ラストマイル配送を効率化するための配送員向けアプリケーションを React Native で開発しています。
ラストマイル(ラストワンマイル)配送とは、営業所から受取人までの配送のことを指し、TODOCUサポーターはこの業務を効率化するためのアプリケーションです。
ブラックフライデーセールで買った荷物をご家庭に届けてくれるのもラストマイル配送なので、身近な存在です。

業務用のアプリですが、Google PlayおよびApp Storeで配信しており、月に2回ほど各ストアにアプリを配信し、週数回OTAアップデートで更新データを配信しています。

記事を書いている2022年12月時点の技術スタックおよび開発チームの内訳は以下のようになっています。

  • 技術スタック
    React Native: 0.69.7
    React: 18.0.0
    Expo SDK: 46 ( Bare Workflow )*1

  • チームの規模
    フロントエンドエンジニア: 4人
    バックエンドエンジニア: 2人*2
    QA: 1人*3

OTAアップデートについては前回の記事に記載しているので割愛しますが、JavaScriptおよび画像などの各種アセットをユーザーに配信することで、アプリストアを介すことなくアプリケーションの機能を更新する仕組みです。
OTAアップデートがあるからReact Nativeを選ぶ、といっても過言ではないほど強力な機能です。

令和最新版!開発〜リリースまで

ストアへのリリース & OTAアップデートの戦略については、前回の記事から変更していません。

前回の記事からの大きな変更としては、 EAS Submit を使うようにしています。これにより、 ビルド〜ストアへのリリースまでがほぼ自動化されています。
ストアリリース専属のエンジニアは存在せず、全ソフトウェアエンジニアが安全にリリースを行うことができるような環境を保っています。
また、開発時は expo-dev-client を使っています。

開発

expo-dev-clientのスクリーンショット

ストアへのリリースをするたびに、GitHub Actionsでexpo-dev-clientをEAS Buildを使ってビルドし、開発者はそちらをインストールして開発する、という運用にしています。
各開発者でアプリをビルドせず、ビルド済みの開発用アプリケーション(expo-dev-client)を使い、基本的にはシミュレーターではなく実機を使って開発しています。*4
これにより、Node.jsの環境さえあれば、即座にアプリケーション開発ができる状態を保っています。

docs.expo.dev

React Nativeアプリを開発する場合、 各開発者毎に環境が異なっていてアプリがビルド出来なくなった、等ハマりがち……。*5
expo-dev-clientを使ってビルド済みのバイナリを利用して開発するので、Xcodeの環境や開発用の署名などを意識する必要がなく、機能開発に集中して開発できています。
特にTODOCUサポーターの機能はJavaScriptだけで完結できるものが多く、普段はアプリをビルドする必要がないという点が207にマッチしており、expo-dev-clientを導入後、アプリのビルドまわりでハマることが激減しプロダクト開発に集中できています。

テスト

207ではE2Eテストを導入しており、テスト自動化プラットフォームとして MagicPodを使っています。
こちらは経験豊富なQAチームが主導して進めてくれており、リリース前の回帰テストを行ってくれています。

また、各機能ごとのテストもQAチームで行っており、バグ・仕様の確認をGitHub Issue & Zenhubを使って管理しています。

QAチームが上げてくれる仕様確認のissue

アプリの単体テストはあまり書けていません……。一部のロジックを含むカスタムhookなどは react-test-renderer でテストを書いています。*6

リリース

OTAアップデートとストアリリースを組み合わせています。ライブラリのアップデートやASO(App Store Optimization)の観点からも、常にOTAアップデートだけで運用するのではなく月に2回ほどアプリストアにバイナリを登録して配信しています。

OTAアップデートの運用については以前書いた記事から変わっていませんが、ストアへのバイナリ登録には、EAS Submitを導入して活用しています。

docs.expo.dev

iOSアプリをApp Storeに登録する時、通常はTransporterを使って登録しますが、EAS BuildとEAS Submitを使うことで、アプリビルド〜審査の直前まで自動化することができています。
地味ですがちょっとしたひと手間が無くなって便利!セットアップさえしたら、EAS Buildのオプションに --auto-submit を付けるだけです。

運用

React Nativeのアップデート戦略

基本的にはExpo SDKのバージョンに合わせています。Expo SDKは最新の2バージョンをサポートしているため、サポート期間中にExpo SDKおよびReact Nativeのバージョンをアップデートしています。
React Native Upgrade Helperが提供されているので、React Nativeの更新はこちらを適用するだけで大丈夫です。例えばExpo SDK45から46へのアップデートをする際のReact Nativeの差分は以下になります。
Upgrade React Native applications

1つ重視していることとしては、Upgrade Helperの差分を適用しやすいように書くようにしています。
例えばReact Native Firebaseなど、 AppDelegate.mm を一部変更する必要のあるライブラリは多く、React Native本体のコードと独自に拡張したコードが混じりがちです。
無秩序だとアップデートがかなり辛くなるので、コード内にコメントを書いてアップグレードのパッチを適用しやすくなるように工夫しています。 *7

監視

SentryとNew Relicを使っています。
特にNew Relicは2022年に導入を開始し、障害発生時の調査に役立っています。
とはいえ100%活用できているとは言えないため、ここはもっと活用する予定です。react native newrelic agentが公式で提供されているため導入を進めています*8

newrelic.com

今後

EAS Update

EAS Update が正式にリリースされたので、expo-updatesからEAS Updateへの移行を進めています。
来年中にはアップデートできるはず!!

New Architecture

React Native 0.68より導入された New Architecture はまだ有効化できていません。
周辺ライブラリの対応も必要なので有効化への道は長そう…。

reactnative.dev

おわりに

この記事は、 207 Advent Calendar 2022の記事でした。

qiita.com

最後にいつもの宣伝で、

207株式会社では、レガシーな物流業界の変革に挑む配達員向け効率化アプリ「TODOCUサポーター」を開発しています。 GraphQLでガンガン開発していきたいメンバーを大絶賛募集中です!

もし少しでもご興味がありましたら以下のnotionをご覧ください!

207-inc.super.site

*1:Expo SDK 38のタイミングでExpo ejectし、初期リリースからおよそ3年経っています。記事執筆時点でExpo SDK47が出たばかり。

*2:正社員の数のみ。業務委託の方が多いです。

*3:副業で経験豊富なQAの方が1名関わってくれていて、テスト自動化などかなり助かってます

*4:シミュレーターを使って開発することもあります。TODOCUサポーターは配達のアプリでGPSを利用するため、実機のほうが都合がいいという事情もあり実機を使って開発することが多いです

*5:Swift、Xcodeのバージョン違い、Apple Silicon使ってる、などなど……。iOSだけでなくAndroidについてもセットアップする必要があるので、さらに大変

*6:バックエンドのコードについては、コードカバレッジが90%を超えています。

*7:AppDelegate.mからAppDelegate.mmへの変更は差分が多く大変だったため、expo-template-bare-minimumからコピーしてきて、Firebaseなどをセットアップし直す、という方法で乗り切りました。

*8:react-native-newrelic-agent@0.0.1がリリースされたタイミングで一度導入しましたが、Out of Memoryのエラーでクラッシュする事象が頻発し、agentを消してリリースしたところ発生頻度が減ったという経緯があるので導入に慎重になっています