自己紹介

植松啓誠氏(以下、植松):本日は「出前館のReact Native開発のこれまでとこれから」という題目で発表します。植松と黒澤です。よろしくお願いします。React Nativeという文脈上、2人のバックグラウンドから紹介させてください。

私は植松と言います。2019年に通称UIT、Frontend開発センターに、フロントエンドのエンジニアとして中途入社しました。主に「LINE証券」や「LINEほけん」といった、金融系のサービスのフロントエンドを担当してきました。2021年2月から出前館に出向して、出向してからはドライバーが使うアプリの改修や、現在はみなさんが使う「出前館」のアプリの開発を担当しています。

現在、京都オフィスに所属していて、渡月橋まで徒歩5分の嵐山に住んでいます。最近はずっと『Apex Legends』や『VALORANT』にハマって夜な夜なプレイをしています。僕個人のバックグラウンドとしては、10年以上フロントエンドの領域で、主にReact、VueなどのSPA開発をしてきました。

黒澤慎治氏(以下、黒澤):黒澤慎治と言います。iOSエンジニアとして、Swift、Objective-Cを使用したiOSアプリの開発を4年ほど行ってきました。2020年にLINEに入社し、LINE公式アカウントをSwiftを使用して開発していました。2021年4月から、出前館アプリの開発を行っています。

ReactおよびReact Nativeを使用した開発は出前館アプリが初めてだったので、日々学習をしながら開発をしています。4月に京都に引っ越ししたので、落ち着いたらお寺巡りなど、京都観光を楽しみたいなと思っています。

セッションのアジェンダ

植松:本セッションでは、大きく分けて3つの項目に関してお話したいと思います。1つ目はそもそも「なぜ出前館の開発者が、LINE DEVELOPER DAYで話しているのか?」を知らない方もいると思うので、出前館とLINEの関係や、出前館のシステムの全体像についてお話します。

次に出前館アプリチームのこれまでの体制の変化や、現在の開発チームが取り組んでいること、開発文化などをお話します。最後に、出前館のモバイル開発で大変だったところと、解決策についてお話したいと思います。

出前館のシステム

最初に、出前館とLINEについてです。まずは出前館について紹介させてください。日本の方は知っている方も多いと思いますが、出前館は日本で最大級のフードデリバリーサービスです。PC・スマートフォンのブラウザ、もしくはiOS/Androidアプリから利用可能です。

数字で見ると、出前館では95,000以上(2021年10月時点)の加盟店に協力いただき、アクティブユーザーも730万人を超えました。ユーザーはこの1年で約2倍に増え、サービスとして大きな成長期を迎えていると開発をしていて感じます。

そんな出前館ですが、注文時にユーザーの方々に見えている部分は出前館アプリもしくはWebブラウザの画面だけですが、その奥でさまざまなアプリやシステムが動いています。配達の仕組みは大きく分けて2種類あります。

1つ目が、加盟店側ですでに配達の仕組みを持っている場合、出前館は店舗への注文の連携が主な役割になります。ユーザーが注文をすると出前館経由で店舗へ情報が連携され、店舗が雇用する配達員の方々がユーザーへ商品を届けます。

2つ目がシェアリングデリバリーの仕組みです。シェアリングデリバリーでは先ほどと同様に、店舗への注文情報を提携します。さらに出前館の配達員に情報を連携して、出前館の配達員が店舗に商品をピックアップし、ユーザーのもとへ届ける仕組みです。これらの仕組みを実現するために、さまざまなシステムが存在しています。

例えば、ユーザーが出前館に注文を行ってから、配達員の方々にオーダー情報を配信する配達アプリ。加盟店が注文情報を確認するアプリや、商品の情報を管理する管理画面。

また、加盟店の売り上げや配達件数、人気のある商品などを可視化し、店舗で利用する分析ツールなども提供しています。それら多くのシステムが、1つの注文に対して動いています。現在、これらの各システムに多くのLINEのエンジニアが関わっています。

どうしてLINEのエンジニアが出前館の開発に関わっているのか

では、そもそもなぜLINEのエンジニアが出前館の開発をしているのかを知らない方も多くいると思うので、LINEと出前館の関係について軽く説明させてください。実は、出前館とLINEは2016年から資本業務提携というかたちで携わっていました。

2017年には「LINEデリマ」という、フードデリバリーサービスをリリースしました。2019年には「LINEポケオ」という、テイクアウト注文ができるサービスをリリースしました。LINEデリマ、LINEポケオともにユーザーが操作するアプリはLINEで開発・運営されていましたが、その後ろでは出前館のシステムやノウハウが活かされていました。

そして2020年3月の資本業務提携を契機に、LINEの各サービスと出前館を統合し、1つのサービスとして成長を加速させるため、LINEのエンジニアが関わるようになりました。最初のアプリのメンバーがジョインしたのが、2020年5月です。最初は加盟店やドライバーが利用するアプリをメインで見ていましたが、2021年4月から出前館アプリの開発に携わり始め、これまで約半年間程度、開発に参加してきました。

このような歴史があり、現在、LINEのエンジニアが出前館の開発に関わるようになっています。

ここからは、この半年間で出前館アプリチームとしてどのような開発体制、開発文化の変化をしてきたのかを紹介したいと思います。

出前館アプリ開発チームについて

まずは現在の出前館アプリ開発チームについて紹介します。アプリチームは、東京と京都の2拠点を中心にメンバーがいます。また、開発パートナーの方が岡山から参加をしていたりします。リモート開発の体制はもちろん整っているので、SlackやZoomを使って、密にコミュニケーションを取りながら日々開発を行っています。

また出前館全体でいうと、CSの方が鹿児島を拠点としていたり、QAの方々が東京・福岡。また、サーバーサイドを含む開発メンバーは大阪・京都・東京を中心に、さまざまな場所から一緒に開発・運営をしています。

出前館アプリの開発チームですが、僕らがチームにジョインするまでは、外部開発パートナーの2名で開発をしていました。しかも2名でPC・スマートフォン・ブラウザ版の出前館と、iOS/Androidのアプリの開発をすべて行っていました。

もちろん2人のエンジニアでブラウザ・アプリの企画、改修案件をこなしながら保守性などを考慮した開発を行うことは難しく、いろいろ妥協をしながら開発を行っていたと聞いています。またこのリソースの少なさが、React Nativeの選定理由の1つでもありました。

そして、現在の出前館アプリの開発チームのメンバーです。4月から徐々にメンバーが増え、現時点でiOSエンジニアが4名、Androidのエンジニアが2名、フロントエンドが1名、LINEから出前館アプリの開発に参加しています。引き続き、外部開発パートナーの方にもお手伝いいただいています。

2名でWeb・アプリともに開発をしていたところから、アプリだけで10名近くのエンジニアが関わる体制に変化しました。

個人的に特徴的なのが、フロントエンドではなくネイティブのエンジニアが多く参加していることです。アプリ開発の上でどうしても両OSの専門が必要な場面であったり、調査が必要な場面が出てきますが、チームに共有するとおおよそのOS依存の設定や改修が必要な場面に、比較的容易に解決できるのが現在のチームの一番強いところだと思っています。

もちろん、今までJavaScriptをメインに開発をしていない人がほとんどなので、学習コストなどはかかります。後ほど黒澤からネイティブエンジニア視点で、React Nativeを触り始めた時の学習コストや、どう学習を進めたのか話が聞けると思います。

体制変化の中でアプリ開発チームが取り組んできたこと

次に、体制が変わっていく中でアプリ開発チームとして取り組んできたことをお話します。先ほども紹介しましたが、アプリ開発はもともと2名で行っていました。そこで、まずチームにジョインしてから、チーム開発を行うための土台作りから始めなければなりませんでした。少人数での開発で一番発生しやすい課題は、さまざまな開発フェーズが属人化していくことだと思います。

出前館アプリでも同様に、仕様面やビジネスロジック、またはビルド環境などが人に依存している状況でした。今まで2名での開発・改修・運用に適した、もしくはリソース的にそうせざるを得なかったやり方でしたが、今後チームとして開発を進めるため、またサービスとして安定的なプロダクトを供給し続けるために、ある程度の標準化・ルール作りをして言語化しておくことが必要でした。

そのため、チームで開発するにあたり、基本的なルール、一貫性を持った開発、継続しやすい開発を行えるような土台作りを行いました。

まずはアプリの開発・運用に関して、基本的なルールを決めました。アプリのバージョンに関してですが、React Nativeには大きく分けてバイナリリリースとOTAでのリリースがあります。

OTAとはOver-The-Airの略で、JavaScriptバンドルのみを個別で配信する機能です。OTAを利用することにより、ストア申請をせずアプリの更新が可能になっています。バージョンに関しては計画的なバイナリのリリース、計画的なOTAのリリース、また問題が発生した際のhotfixを考慮してルールを再作成しました。

単純ですが、具体的にはメジャーバージョンをバイナリアップデート、マイナーバージョンをOTAアップデート、hotfixをパッチバージョンとしてインクリメントするかたちにしています。出前館アプリのマイページから現在のバージョンが見れるので、現在配信されているものがどういう状況なのか想像できると思います。

次にGitのルールですが、アプリチームではいわゆるGitLab-flowをベースにコードの管理をしています。React Native開発で1つ気をつけなければいけないのが、ネイティブモジュールの追加・更新が必要なものをOTA配信してしまうと、JavaScriptバンドルのみ更新されて、不具合の原因になってしまうこともあります。

そのため、先ほどのバージョンルールによるバイナリリリースの明確化と、リリースブランチによるソースコードの管理を行っています。

チーム開発に移行してからスクラムも導入しました。チーム開発への移行期でキャッチアップしなければならないことも多いので、現在は1weekスプリントで運用をしています。タスクマネジメントはJira Softwareで行っていますが、アプリチームとして管理できていなかったものが多々あったので、管理しやすいようにボードやラベル、エピックなどを利用した整備や起票時のルール作りなども適宜行ってきました。

次に、コードとして一貫性を保つために行ったことです。タイプシステムについてはflowやTypeScriptをみなさん使っていると思いますが、出前館では僕たちがジョインした時、コードですべてがTypeScript化されていました。しかしJavaScriptからの移行だったので、さまざまな箇所でanyが使われており、現在は粛々とanyの排除を行っています。

少なくとも新規で実装する画面では、noImplicitAny前提で実装を行うようにしています。Linter/PrettierはWebフロントエンド開発ではほぼスタンダードなものですが、既存のコードベースでは利用していませんでした。僕がプロジェクトに入って最初に行ったプルリクエストが、アプリ内の全コードをフォーマットすることと、Lintエラーの修正でした。チームとしてインデントや細かな箇所の指摘をしないようにルールを与えることで、レビュー負荷を下げるのが一番の目的です。

また、SonarQubeはコードの静的解析ツールです。各修正・機能実装内でのコードのクオリティを担保するための1つの指標として導入しています。現在、大規模なリファクタリングも行っていますが、複雑性などでファイルを評価してくれたりするので、優先順位を決める際にも参考にしています。

「2人で開発」と聞いて想像できると思いますが、当時はテストに充分に割けるリソースはありませんでした。現在はユニットテストでロジックのテスティングをメインに、粛々とテストが追加されていっています。

また、ビジネスロジックとUIロジックが複雑に絡み合っていたので、スナップショットテストも導入し、リファクタリング後に余分なUI差分が出ていないか、他のコンポーネントに影響を与えていないかなどの確認に利用しています。

E2Eテストに関して検討はしましたが「今じゃない」という判断で、バックログにチケットだけ眠っています。眠ってしまってはいますが、メインのフローで重要な決済の部分などのみ、優先して導入することも検討しています。これらをチームとして、一貫性のある開発・保守をするために導入してきました。

最後に、継続的に開発を行うために整備した部分です。1つ目がビルド環境です。詳しくは後ほど黒澤から話しますが、以前は個人PCのローカル環境でビルドを行って、成果物をストアへアップロードしていました。Node.jsのバージョンであったりXcodeのバージョンなど、目に見えない箇所でさまざまな差分・依存がありました。

現在はbitriseというサービスを利用しており、bitrise上でOTAビルドの作成やバイナリビルドの作成のワークフローを管理しています。ブラウザでワンクリックすればQA用のバイナリやリリース用のバイナリを自動で作成し、ストアへアップロードするまで個人の環境に依存せずに完了する状態になっています。特にビルドフェーズに関しては、それぞれのネイティブのエンジニアの知識が存分に活かされていると思います。

またGitHub Actionsも活用し、テスト、Lint、Prettierなどのチェックの自動化、またプルリクエストの差分をSonarQubeで静的解析を行うことによって、コードレビューの負荷を下げて開発により多くの時間を割けるようにしました。ここまでがチーム開発の土台作りとして、今まで行ってきた改善です。

出前館開発チームが今取り組んでいること

最後に、僕からは出前館開発チームが今取り組んでいることをお話します。大きく分けて3つ、メンテナンス性、安定性、ユーザー体験の向上に取り組んでいます。メンテナンス性の向上に関してですが、既存のコードベースでビジネスロジック、UIロジックが複雑に絡み合っているため、複雑性の解消に取り組んでいます。後ほど黒澤からリファクタリングについて詳しくお話します。

また、多くのサードパーティパッケージも利用しており、各パッケージのアップデートに追従しようとしていますが、React Nativeとの互換性など、通常のReactの時よりも依存関係が複雑なため、少しずつ最新化を進めています。renovateの導入も行い、パッケージのアップデートを追うようにしています。

ビジネスロジック・UIロジックの分離と先ほどお話しましたが、WebとアプリではUIの共通化が進んでいます。Web・アプリでそれぞれフロントにあるビジネスロジックを、BFF(Backend For Frontend)側に移行を進めています。React NativeでTypeScriptを書いているアプリエンジニアは、BFFの開発にも参加したりしています。

次に安定性の向上に関してですが、現在、出前館ではアプリだけでなく、出前館全体のシステムとして大きな改善が行われています。APIの変更などに対して、今までアプリ・Webで対応が必要でしたが、開発コストを下げるためにも、先ほどお話したBFFへのビジネスロジックの移行が効果的に働くと思っています。

クラッシュに関しては、sentryやappcenter-crashesでログの収集をしています。現状、クラッシュ率を0.1パーセント程度にキープできている状況なので、今後もキープをしていきたいと思っています。ユーザー体験の向上に関しては日々改修を行っておりますが、大きなトピックとして、出前館のデザインシステムの構築中です。今後、徐々にデザインシステムを適用していき、アプリとして出前館としてユーザビリティの向上を目指しています。

デザインシステムを導入するメリットとしては、サービスの急成長に伴い、企画・デザイナー・エンジニアで共通認識を持って不要なコミュニケーションコストの削減や、安定したデザイン品質のマネジメントが可能になると思っています。

結果的にプロジェクト進行の高速化や高品質化、ブランド認知の向上が見込め、エンジニアリングの観点はもちろん、ビジネス観点でも大きなメリットが得られると考えています。

また、UIがWebと共通する部分が多いので、React Native for Webの検証や、React GUIなどの可能性も含めてウォッチしています。出前館のWebもReactを利用しているので、入力インタフェースやネイティブが強く関わる部分以外は、デザインシステムの構築とともに共通化する検証も行う予定です。

以上、2021年4月から出前館アプリの開発に参加して、出前館アプリ開発チームとして行ってきたことです。現在、出前館アプリ開発は土台が整い、安定性を保ちつつ、スピード感のある開発を行える環境ができあがってきました。

これからさらにサービスの成長を加速させるために、さまざまなところから開発・サービスの改善を行っていく予定です。僕からは以上になります。ありがとうございました。ここからは黒澤にバトンタッチしたいと思います。

後半につづく