はじめに
こんにちは!プロダクト開発部 ユーザープラットフォームグループの川根です。現在、React Native + React Native for Webで新規プロダクトを開発しています。
当グループでは、新規プロダクトの他にも React Native 製の Pep Up というアプリを開発・運用しており、React Native エンジニアはモバイルアプリチームとしてプロダクト間を横断して知見を共有し合っています。私はチームに 2022 年の 4 月から参加しまだ 1 年弱ですが、短い中で感じたチームの強みの1つが、タスクの粒度を適切なサイズまで分解できていることでした。
本記事では、モバイルアプリチームが開発のバッチサイズを小さくするために行っているタスク分解の方法について、紹介したいと思います。
そもそもなぜタスクが大きいといけないのか
タスクが大きい弊害は色々ありますが、代表的なものとして以下のような点が挙げられます。
- 1 つのタスクに多くの問題を孕んでしまう可能性があり、問題の把握・対処が難しくなる
- Pull Request が大きくなり、変更・追加箇所を見通すのが困難になり、レビューコストが雪だるま式に大きくなる
- レビュー待ちの時間が長くなり、依存関係にあるタスクの Blocker になる
タスクを小さくすることで、上記の弊害を解消することができます。
どうやってタスクを小さくしているか
ユーザープラットフォームグループでは、アジャイル開発のフレームワークとしてスクラムを導入しています。ユーザーストーリー単位で PBI(プロダクトバックログアイテム)を切り、スプリントではそれを SBI(スプリントバックログアイテム)に分割しますが、SBI をできるだけ小さくし、SBI 単位で Pull Request を作成することでタスクのバッチサイズを小さくしています。
SBI を小さくすると、チケットによっては成果物(インクリメント)がユーザーに提供可能なものに至らないので、その場合は開発者をユーザーとし、開発者が利用可能な成果物をインクリメントとしています。エンジニアが利用可能なインクリメントは、以下の概念やツールを利用して定義・作成しています。
まず、PBI 完成までの成果物を以下のレイヤーに分けて考えます。
- UI component layer
- Application layer
UI component layer
UI component layer では、Atomic Design の Atoms〜Template までの概念を借用してチケットを分割します。多くのタスクは以下の 3 つのレイヤーごとにいくつかのチケットに分けることができます。
- 汎用コンポーネントが利用できること(Atoms・Molecules 相当)
- feature コンポーネントが利用できること(Organism 相当)
- レイアウトファイルが利用できること(Template 相当)
分割したチケットごとに Storybook に登録し、チケット単位で Pull Request を作成することで、成果物を小さな単位で確認可能にします。
Application layer
ここでいうApplication layer は、Atomic Design で言う Pages に相当します。
新規プロダクトでは GraphQL を使用してスキーマ駆動開発を行っているので、まずは GraphQL Schema を定義し、それが最初の成果物になります。Schema 定義はクライアントサイド・サーバーサイド問わず比較的ドメイン知識を持っているメンバーが任意で行っています。
Schema が決まってしまえば、GraphQL codegen を使って API クライアントを自動生成し、UI component layer で作成した Template に Page コンポーネントを通じて API レスポンスを注入するだけです(必要に応じて、レスポンスの整形や mutation 用データの加工、UI の状態管理などを行うために hooks を作成します)。
API 開発が未完了の場合は、MSW を使用してモックしたレスポンスを返します。そうすることで、サーバーサイドタスクの進捗との依存関係を排除して進めることができます。
まとめると、多くのタスクは以下 3 つのレイヤーに分割できます。
- GraphQL Schema の定義
- Page コンポーネントの作成と Navigation への組み込み(この時点では、Template 層の Storybook で使用したモックを使い回します)
- API クライアントの作成と、Page コンポーネントから Template への注入(必要に応じて MSW を使用してモックしたレスポンスを返します)
これらのレイヤーは、以下の 3 つをそのまま成果物としてチケット化し、それぞれPRを作成します。
- GraphQL Schema が利用できること
- Application へのPageの繋ぎ込みが確認できること
- Application へ実データ(または MSW でモックしたレスポンス)が反映されていること
Applicationレイヤーのタスクは大きくなりがちので、必要に応じて機能や反映箇所の単位でさらにタスクを分割しています。
効用
これらの分類ごとにタスクを分けることで、各チケットごとに不確実性を抑えてタスクを進めることができています。また、PR の大きさを抑えることでほとんどの PR のレビュー時間が 30 分以内に抑えられ、レビュー依頼から完了までのリードタイムも半日ほどになっています。
まとめ
アプリ開発の技術選定には 、Flutter などのクロスプラットフォームフレームワークや、Kotlin・Swift などのネイティブアプリ開発が選択肢として上がりますが、React Native は JavaScript・TypeScript エコシステムの資産を活用してアプリ開発ができるので、その点を大きな魅力に感じています。
Storybook駆動でUI開発ができることや、MSWを使用して手軽にモックしたレスポンスを返すことができることは、大きな利点ではないでしょうか?Storybookへの公開をエンジニアへのインクリメントとして、開発のバッチサイズを小さくすれば、クライアントサイド開発の複雑性を下げることができます。
おわりに
最後になりましたが、React Native で医療・ヘルスケア領域の課題解決に一緒に取り組んでいただける方、興味がありましたらお気軽にお声かけください。
JMDC では、私の所属している新規プロダクト開発チーム・モバイルアプリチーム以外にも、多方面でエンジニアを募集中です。
開発系の募集職種は下記に一覧化されていますが、ご興味を持たれた方はカジュアル面談から可能ですので、JMDC Tech (@jmdc_tech) / Twitter までご連絡いただければ幸いです。