Slide 1

Slide 1 text

1 メルペイのスケーラビリティを支える マルチモジュール開発 merpay Tech Talk 2021/03/18 Masamichi Ueta @masamichiueta

Slide 2

Slide 2 text

2 ● マルチモジュール開発について ● メルペイの現在の構成 ● 現在の構成になるまでのプロセス ● 今後取り組んでいきたいこと 本日の内容

Slide 3

Slide 3 text

3 マルチモジュール開発について

Slide 4

Slide 4 text

4 ● 今回はモジュール = フレームワークやスタティックライブラリと考える ● マルチモジュール開発 = 複数のフレームワークやライブラリを組み合わせてア プリを開発すること ● サードパーティー、プロジェクト内のフレームワークやライブラリを使う場合を想 定 マルチモジュール開発

Slide 5

Slide 5 text

5 アプリターゲット ライブラリ1 ライブラリ2 アプリの構成 1 ● 1つのアプリターゲット ● パッケージマネージャーを使って ライブラリを管理

Slide 6

Slide 6 text

6 ● アプリを各層に分割 ○ 層が分割されて構成がわかりやす くなる ○ よく使う機能をまとめておける ○ Extensionでも共通して使える ○ ビルドタイムを短縮できる場合があ る アプリの構成 2 アプリターゲット ライブラリ1 ライブラリ2 UI エンティティ

Slide 7

Slide 7 text

7 ● アプリの機能を、機能ごとに分割 する ○ 対象の機能を備えたサンドボックスア プリを作って開発できる ○ 複数チームで同時開発しやすくなる [参考] ● モバイル決済アプリの作り方 @kenmaz https://speakerdeck.com/kenmaz/how-to-develop-a-mobil e-payment-app ● Developing Apple Pay In-App Provisioning in merpay @kenmaz https://speakerdeck.com/kenmaz/developing-apple-pay-in -app-provisioning-in-merpay アプリの構成 3(メルカリ/メルペイ) アプリターゲット ライブラリ1 ライブラリ2 UI エンティティ 機能1 機能2 機能3

Slide 8

Slide 8 text

8 メルペイの現在の構成

Slide 9

Slide 9 text

9 メルカリアプリ アプリターゲット 機能 機能 共通 共通 ・・・ 外部ライブラリ 外部ライブラリ ・・・ ・・・ デザインシステム 共通エンティティ ・・・ 共通外部ライブラリ 機能 機能 共通 共通 ・・・ 外部ライブラリ 外部ライブラリ ・・・ ・・・

Slide 10

Slide 10 text

10 メルカリアプリ アプリターゲット 機能 機能 共通 共通 ・・・ 外部ライブラリ 外部ライブラリ ・・・ ・・・ デザインシステム 共通エンティティ ・・・ 共通外部ライブラリ 機能 機能 共通 共通 ・・・ 外部ライブラリ 外部ライブラリ ・・・ ・・・

Slide 11

Slide 11 text

11 ● 17個の機能モジュール、3個の共通 モジュール ● 機能モジュール間で連携しつつも直 接の参照関係はない ● 各機能開発時はそれぞれのサンド ボックスアプリで確認 ● 機能モジュールは全てスタティックラ イブラリ+専用バンドル、共通モ ジュールはダイナミックフレームワー ク クーポン QR NFC コア 通信 XXX メルペイの詳細 ・・・ アプリ アプリ アプリ アプリ スタティックライブラリ + バンドル ダイナミックフレームワーク

Slide 12

Slide 12 text

12 ● 新規PJを立ち上げる場合は1コマン ドで新機能モジュールを生成 ./bin/init_framework.sh FRAMEWORK_NAME ● 機能モジュールはスタティックライブ ラリなので、個数が増えても起動時 間に影響を与えない ● 複数のプロジェクトを同時に開発し ていけるスケーラブルな構成 クーポン QR NFC New! コア 通信 XXX 新規プロジェクト立ち上げ アプリ アプリ アプリ アプリ アプリ スタティックライブラリ + バンドル ダイナミックフレームワーク ・・・

Slide 13

Slide 13 text

13 現在の構成になるまでのプロセス

Slide 14

Slide 14 text

14 ● マルチモジュールで開発 ● 機能モジュール3個、共通モジュール1個くらいの規模 ● ダイナミックフレームワーク ● 機能モジュール間での依存は特になし メルペイ立ち上げ時

Slide 15

Slide 15 text

15 ● 機能モジュール間での参照が複雑になってきた ○ 機能モジュール間で相互に参照する必要が出てきた ○ 1つの機能モジュールが複数の機能モジュールにリンクされる ● 特定の機能モジュールに多くの機能が入っていた ○ 新規モジュール作成に割と手間がかかる ○ モジュールに分割すべき規模の指標がなかった ○ xcodeprojのコンフリクト ● モジュール分割したいが増えすぎても起動時間に影響を与えてしまう ○ > You can reduce your app’s launch time by limiting the number of frameworks you embed https://developer.apple.com/documentation/xcode/improving_your_app_s_performance/reducing _your_app_s_launch_time ● 分割したいけどなかなか分割できない状態 開発規模が大きくなるに連れて出てきた課題

Slide 16

Slide 16 text

16 ● 機能モジュール間で直接参照を しなくても良い仕組みを作る ○ 各モジュールに含まれる画面を抽象 化し共通モジュールに定義 ○ 各モジュールから別のモジュールの 画面を呼び出せるようにする 課題をどう解決していったか 1 public enum MerpayScene { case walletKit(scene: MerpayWalletKitScene) case nfcKit(scene: MerpayNFCtKitScene) ... } public class MerpaySceneFactory: MerpaySceneFactoryType { public static let shared = MerpaySceneFactory() private var factories: [MerpaySceneFactoryType] = [] public func register(factory: MerpaySceneFactoryType) { factories.append(factory) } public func viewController(for scene: MerpayScene) -> UIViewController? { for factory in factories { if let viewController = factory.viewController(for: scene) { return viewController } } return nil } guard let vc = dependency.viewController(for: scene) else { return }

Slide 17

Slide 17 text

17 ● XcodeGenによるプロジェクト管理コスト低減 ○ メルカリチームで @kateinoigakukun 中心にXcodeGen化進めていた ○ メルカリに追従する形で XcodeGen化 ■ xcodeprojファイルのコンフリクトがなくなる ■ 機能モジュールをテンプレート化してコマンドで生成することで新規モジュール作成の手 間が省ける ○ 機能モジュールのサンドボックスアプリのターゲット追加も容易に ○ XcodeGenではなくてもいいがマルチモジュール化には何らかの生成ツールが必要 課題をどう解決していったか 2

Slide 18

Slide 18 text

18 ● 機能モジュール間の依存関係を整理、直接の参照を解消 ○ 1で、機能モジュール間で直接参照しなくてもよくなったため、モジュール内で参照しあっていた 部分を別モジュールに分割 ○ 機能モジュール間での直接の依存関係をなくす ● 機能モジュールをスタティックライブラリ化 ○ 機能モジュール間での依存関係がなくなったことでスタティックライブラリ化が容易になった ○ 機能モジュールが増えることによる起動時間への影響をなくす ● 1つの大きなフレームワークを8個のスタティックライブラリに分割 ○ 1つの機能モジュールの規模感もできてきた 課題をどう解決していったか 3

Slide 19

Slide 19 text

19 参考: スタティックライブラリ化で起動時間も早く

Slide 20

Slide 20 text

20 ● 新規プロジェクト立ち上げ時の開発がやりやすくなった ○ 新規機能モジュールの生成が容易 ○ 機能モジュール間の連携方法が明確 ○ 複数チームで複数の機能モジュール開発ができる ● 新たな開発プロセスもできるようになってきた ○ 次のkuさんの発表で詳しく ● モジュールごとのテストカバレッジも把握しやすくなった 現在のマルチモジュール開発構成でよくなったこと

Slide 21

Slide 21 text

21 ● 規模が大きくなりモジュールも増えビルド時間が増えてきたので、ビルド時間を 減らす方法を模索していきたい ● OSサポートの関係でSwiftUI/Combineをまだ使っていないが、そろそろ SwiftUIのアーキテクチャ・新規モジュールでの採用を検討していきたい 今後取り組んでいきたいこと 興味を持っていただけた方、ぜひ一緒にやっていきましょう 応募 https://mercari.wd3.myworkdayjobs.com/ja-JP/mercari_external/job/Rop pongi/Software-Engineer--iOS--Merpay-_JR-000000306-6