見出し画像

Androidのバージョン管理をbuildSrcを使うようにリファクタリングした理由

最近業務のプロジェクトのバージョン管理をextブロックを使った形式から、buildSrcを使った形式にリファクタリングしました。

Androidのライブラリのバージョン管理方法として定番なのはbuild.gradle内でextブロックで変数定義するという方法です。Android公式でも紹介されている方法です。

対して、最近はbuildSrcとKotlin DSLを使った定数定義方法でのバージョン管理方法もあります。

双方それぞれメリット・デメリットがあり、結論的には「好み」の世界かなと思うのですが、今回なぜbuildSrcを使った形式にリファクタリングしたのかをつらつらと書いていきたいと思います🙋‍♂️

extブロックでのバージョン管理

もともとプロダクトではextブロックによる変数を定義してのバージョン管理をしていました。

buildscript {
   ext.kotlin_version = '1.3.61'
   ext {
       // gradle
       gradleVersion = '3.6.2'

       // App version
       versionName = '2.0.0' // X.Y.Z; X = Major, Y = minor, Z = Patch level
       versionCode = 7

       // SDK and tools
       compileSdkVersion = 29
       minSdkVersion = 21
       targetSdkVersion = 29

      // App dependencies
       androidGradlePluginVersion = '3.4.1'
       appcompatVersion = '1.1.0-beta01'
       activityVersion = '1.1.0'
       cardviewVersion = '1.0.0'
       archTestingVersion = '2.0.0'
       arcoreVersion = '1.7.0'
    }
}

使う側はこんな感じですね。

dependencies {
   // Kotlin
   implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
   // Coroutine
   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutinesVersion"
   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutinesVersion"
   // Instrumentation tests
   androidTestImplementation "androidx.test.ext:junit:$rootProject.junitExtVersion"
   androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.espressoVersion"
   // Logger
   implementation "com.jakewharton.timber:timber:$rootProject.timberVersion"
}

メリット
- build.gradleにすぐ書けるので導入コストが低い
- Android Studioからバージョンのサジェストがされる(新しいバージョンがあるよ!とか)

デメリット
- Android Studioの補完が効かない
- 定義ジャンプができない

低コストでバージョン管理ができるようになるのでいいですね。基本的にはこのextを使ったやり方で問題ないと思います。

buildSrcでのバージョン管理

buildSrcも特には設定は必要ありません。プロジェクトのルート直下にbuildSrcと言うディレクトリとbuild.gradle.ktsを作成してビルドすれば使えるようになります(とは言え手順があるのできちんと調べて導入した方がいいです。)

package dependencies

object Dep {

   object Kotlin {
       const val version = "1.3.72"
       const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$version"
   }

   object AndroidX {
       const val coreKtx = "androidx.core:core-ktx:1.2.0"

       const val activityKtx = "androidx.activity:activity-ktx:1.1.0"
       const val appcompat = "androidx.appcompat:appcompat:1.1.0-beta01"
       const val fragmentKtx = "androidx.fragment:fragment-ktx:1.1.0"
       const val cardView = "androidx.cardview:cardview:1.0.0"
       const val browser = "androidx.browser:browser:1.0.0"
       const val constraintLayout = "androidx.constraintlayout:constraintlayout:1.1.3"
       const val drawerLayout = "androidx.drawerlayout:drawerlayout:1.1.0-alpha03"
       const val vectorDrawable = "androidx.vectordrawable:vectordrawable:1.1.0"
   }
}

このやり方の場合は、Kotlinでバージョン定義などのConst定義ができます。構造的に定義できるので見通しがいいですね。

実際に使う時はこんな感じで書くことができます。

import dependencies.Dep

dependencies {

   // Kotlin
   implementation Dep.Kotlin.stdlib

   // Coroutine
   implementation Dep.KotlinX.Coroutines.core
   implementation Dep.KotlinX.Coroutines.android

   // Logger
   implementation Dep.Timber.timber
}

メリット
- Kotlinで書ける
- build.gradleで使うときに補完が効く
- 定義ジャンプができる

デメリット
- 構築がextに比べて大変
- バージョンのサジェストがされない(2020/05/22現在)
- Android StudioのProject stractureが対応してない(2020/05/22現在)

ここまでextでの管理とbuildSrcでの定義のメリット/デメリットを見てきました。どちらもいいところ悪いところがあるので、好みでもありますし、まあどちらでもいいかなと言う感じですね。

ただ、マルチモジュールで開発している場合は、buildSrcでの補完や定義ジャンプが非常に便利になってきます。

マルチモジュールプロジェクトでのbuild.gradle

最近のAndroid開発ではマルチモジュールで作成することが多くなりました。僕のプロジェクトでもマルチモジュールで開発しています。

マルチモジュール構成のプロジェクトでは各モジュールにbuild.gradleがあり、依存ライブラリもそれぞれに書いていきます。

build.gradleが増えて、何度も同じdependenciesを書いてるうちに、補完がされたり、定義ジャンプでバージョンの確認ができるメリットが勝ってきました。

定義ジャンプのメリット

このbuildSrcでの定義メリットでよく言われるのが補完が効くと言う部分なのですが、僕はそれ以上に定義ジャンプができるメリットが大きいと思います。

このライブラリのバージョンっていくつだったっけ、と言うような時にAndroid Studioでジャンプができるのはとても便利です。ext定義の場合はジャンプできないので、自分でファイルを開くか文字列検索をする必要があってなかなかに面倒です。

逆に、buildSrcの方で定義している側からもジャンプすることができます。Usageジャンプができるので、そのライブラリがどこで使われているかがわかるようになります。これが超便利!

どのモジュールがどのライブラリに依存しているかがわかりやすいですし、どこからも依存されていないライブラリ定義なんかもすぐにわかるようになります。複数モジュールと複数build.gradleがあるマルチモジュールプロジェクトと相性抜群ですね!

まとめ

- 基本的にはextとbuildSrcでそこまで大きな違いはない
- マルチモジュールプロジェクトではbuildSrcが便利!
- マルチモジュールプロジェクトの場合は、build.gradleの数が多くなり、何度も同じライブラリを入れるので補完の強みが出る
- 定義ジャンプができるのでライブラリバージョンの確認がとてもしやすくなる
- buildSrc側から使われている場所にジャンプもできるので、依存しているモジュールがわかる
- どこからも依存されていないライブラリがすぐにわかるようになる!

以上が僕がプロジェクトのバージョン管理をbuildSrcに移行した理由です。まずはextとbuildSrcでのバージョン管理両方を実際に使ってみて、自分の好みと、どっちの方が楽かを天秤にかけて比べてみるといいですね!


この記事が気に入ったらサポートをしてみませんか?