Dependency Hellを乗り越える、基盤ライブラリのメジャーアップデートの勘所 | Wantedly Engineer Blog


こんにちは、Mobile Tech Leadの久保出です。

今回は、モバイルアプリ開発者が定期的に直面する、少し厄介なタスクであるAGP(Android Gradle Plugin)やGradle、Xcodeといった開発基盤に関わる依存性のメジャーアップデートについて、その勘所を共有したいと思います。

とりあえずバージョンを上げてみたら、芋づる式に大量のライブラリのアップデートが必要になり、ビルドが通らなくなってしまった…といった経験をした人は多いでしょう。

この記事が、そんな難易度の高いアップデート作業に立ち向かう一助となれば幸いです。

目次

  • なぜ基盤ライブラリのアップデートは難しいのか

  • 勘所1:公式情報を確認する

  • 勘所2:サードパーティライブラリ

  • 勘所3:自動テストの価値

  • 勘所4:こまめなコミット

  • まとめ

なぜ基盤ライブラリのアップデートは難しいのか

Android開発におけるAGP、Gradle、Kotlin。iOS開発におけるXcodeのアップデート。これらはアプリ開発の根幹を支える重要な要素ですが、アップデートには特有の難しさがあります。

それは、依存関係に共依存性があるためです。よく依存関係地獄(Dependency Hell)と呼ばれます。例えば、AGPを最新版にしようとすると、特定のGradleバージョンやKotlinのバージョンが必須になるケースは珍しくありません。同様に、Xcodeをアップデートすると、今まで使っていたライブラリが新しいビルドシステムに対応できず、アップデートが必須になることがあります。特に、メタプログラミングを駆使するライブラリや、特定のUIを提供するライブラリなどは影響を受けやすいです。

結果として、1つのアップデートが連鎖的な変更を引き起こし、タスクの全体像が見えにくく、非常に難易度の高い作業となってしまうのです。

勘所1:公式情報を確認する

最初にバージョンアップを試してみたくなる気持ちはよく分かります。私も何度もやったことがありますが、基盤ライブラリのアップデートに関しては、そのアプローチは避けた方が賢明です。変更点が多岐にわたるため、手探りで進めるとリリースワークフローでのみ問題が起きるといった、見つけにくい不具合に繋がるリスクがあります。

最初にやるべきことは、公式情報の確認です。

AGPGradleは、バージョンごとの互換性の表を公開しています。メジャーアップデートの際には、詳細な移行ガイドが用意されていることがほとんどです。

これらのドキュメントに目を通すだけで、どのバージョンと組み合わせるべきか、どのような破壊的変更があるのかを事前に把握でき、将来の事故を大きく減らせます。AGPには公式の移行ツールも用意されているので、積極的に活用しましょう。

勘所2:サードパーティライブラリ

公式の移行ガイドを読んだだけでは、残念ながらすんなりとはいきません。次に立ちはだかるのが、サードパーティライブラリの壁です。

基盤となる依存性をアップデートしようとすると、プロジェクトが利用しているライブラリ、特にビルドシステムに深く関わるものが対応しておらず、ビルドエラーを引き起こすことがよくあります。

この問題への対処法は地道です。

  1. ビルドを試みる: エラーログから、どのライブラリが問題を引き起こしているかを特定します。
  2. ライブラリの更新を確認する: 問題のライブラリのGitHubリポジトリやリリースノートを確認し、新しいバージョンがリリースされていないか探します。
  3. アップデートして再度ビルドする: 新しいバージョンがあればアップデートし、問題が解決するか試します。

新しいバージョンがリリースされていればまだ良い方で、時にはメンテナンスが停止しているケースもあります。こうなると事態は深刻で、そのライブラリをプロジェクトから取り除くか、代替手段を検討する必要が出てきます。本来の目的だった基盤アップデートが、予期せぬ大規模な改修に発展してしまうのです。

この経験から得られる教訓は、依存するライブラリは将来的な技術的負債になりうるという認識を持つことです。新しいライブラリを導入する際は、その場の利便性だけでなく、依存関係の多さや、メンテナンスが活発に行われて信頼性があるかといった観点を導入基準に含めることが重要です。また、日々ライブラリをアップデートし続け、ビッグバンアップデートにしないことも重要です。

勘所3:自動テストの価値

ビルドが通り、アプリが起動したとしても、まだ安心はできません。ライブラリのアップデートによって、内部的な挙動が意図せず変わっている可能性があります。

このような変化に気づくために、自動テストが非常に有効です。

  • CIによるユニットテスト・結合テスト: 既存のロジックが壊れていないかを機械的にチェックできます。
  • UIテストの自動化: 画面の表示崩れや、ユーザー操作に対する反応の変化などを検知しやすくなります。

日々テストコードを書くことにより移行時のコストを下げられる反面、テストコード自体もまた依存性を持つことに注意が必要です。大規模なアップデートの際にはテストコード自体も大幅に書き換える必要があるでしょう。

自動テストで全てのデグレを検知できるわけではありません。特に大規模なアップデートの後は、QAチームと連携し、主要な機能について手動でのテストを実施し最終的な品質担保をすべきでしょう。

勘所4:こまめなコミット

最後に、当たり前かもしれませんが、極めて重要な心構えについてです。それは、随時コミットを重ねることです。

依存の依存を一つずつ解決していくプロセスでは、変更が膨大になりがちです。このライブラリのバージョンを上げたら、別の箇所が動かなくなったので、一旦変更を取り消したいという状況は頻繁に発生します。

作業単位でこまめにコミットをしておくことで、

  • 特定の変更点へ安全に戻りやすくなる
  • 変更が膨大になっても、git cherry-pickなどで必要な変更だけを取り込む選択肢が生まれる

など、柔軟な対応が可能になります。

まとめ

モバイルアプリ開発における基盤ライブラリのメジャーアップデートは、計画なしに進めるとDependency Hellに陥りがちな難しいタスクです。しかし、体系的なアプローチで臨めば、そのリスクを大きく下げることができます。

この記事が、皆さんの次回のアップデート作業の助けになることを願っています。


元の記事を確認する

関連記事