[Kotlin] Kotlin DSL로 Migration 하기

Happy Jiwon·2023년 8월 28일
1

Kotlin

목록 보기
5/6

기존에 Java로 작성한 프로젝트를 Kotlin으로 변경하면서 gradle도 Kotlin DSL로 Migration 해야겠다 생각했는데, 하다보니 정리를 할 필요성을 느끼게 되어 작성해보고자 한다.

Kotlin DSL 이란?

DSL 이란 Domain Specific Language의 약어로 특정 분야에 최적화된 프로그래밍 언어를 뜻한다.
상용구 코드를 최소화 하기 위해 명령형 코드 대신 선언적 코드 형식 을 따른다.
Kotlin DSL은 코틀린의 언어적인 특징으로 가독성이 좋고 간략한 코드를 사용하여 Gradle 스크립팅을 하는 것을 목적으로 하는 DSL이다.

빌드 스크립트에서 사용하는 객체, 함수, 속성들은 Gradle API와 적용한 plugin API에서 가져온다.

Kotlin DSL을 사용하는 이유

왜 Groovy DSL 에서 Kotlin DSL로 변경해야 하는지... 의문이 들었다.🤔
Kotlin DSL로 변경하면 아래와 같은 장점이 있다.

  • 컴파일 타임에 에러 확인
  • 코드 탐색
  • 자동 완성
  • 구문 강조
  • IDE의 지원으로 향상된 편집환경
  • 소스코드와 동일한 언어의 사용

반면 단점도 존재한다.

  • 빌드 캐시가 Invalidation 되거나 클린 빌드시에 Groovy DSL보다 느리다.
  • Java8 이상에서 동작
  • 새로운 라이브러리 버전 Inspection 기능 미지원

📌 Kotlin DSL 사용해보기

시작하기 전 아래 활동을 해준다.

  • root 프로젝트에 buildSrc 디렉터리 생성
  • buildSrc 디렉터리 안에 build.gradle.kts 파일 생성
  • 생성한 build.gradle.kts 에서 프로젝트에 Kotlin-DSL 플러그인을 활성화하도록 지시하는 일부 코드를 추가해준다.
plugins {
    `kotlin-dsl`
}
repositories {
    mavenCentral()
}

다양한 블로그를 참고하면 jcenter()로 나와있지만 deprecated 되어서 mavenCentral() 를 사용해주어야 한다.

여기까지 완료했다면 프로젝트에서 Kotlin DSL이 활성화되었을 것이다!!


buildSrc > src > main > java 폴더 생성

위 java 폴더 안에 앱 레벨, 버전 정보나 라이브러리 관련 버전 정보를 저장할 파일들을 생성해 줄 예정이다.

  • AppConfig 프로젝트와 관련된 앱 수준 구성을 한 번에 관리
  • Versions 라이브러리 버전 관리를 한 곳에서 분리
  • Dependencies UI, 테스트 및 기타 타사 라이브러리와 관련된 앱의 모든 종속성이 포함

AppConfig.kt

object AppConfig {
    const val compileSdk = 33
    const val targetSdk = 33
    const val minSdk = 24
    const val versionCode = 1
    const val versionName = "1.0.0"
    const val buildToolsVersion = "29.0.3"
    const val jvmTarget = "1.8"
}

Versions.kt

object Versions {
    // App Level
    const val KOTLIN = "1.6.10"

    // AndroidX
    const val APP_COMPAT = "1.4.1"
    const val MATERIAL = "1.5.0"
    const val CONSTRAINT_LAYOUT = "2.1.3"

    // KTX
    const val CORE = "1.7.0"

    // TEST
    const val JUNIT = "1.1.3"

    // Android Test
    const val ESPRESSO_CORE = "3.4.0"
    
    ... 생략
}

Dependencies.kt

object Dependencies {
    const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.KOTLIN}"
    
}

object Libraries {
    object AndroidX {
        const val APP_COMPAT = "androidx.appcompat:appcompat:${Versions.APP_COMPAT}"
        const val MATERIAL = "com.google.android.material:material:${Versions.MATERIAL}"
        const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout:${Versions.CONSTRAINT_LAYOUT}"
    }

    object KTX {
        const val CORE = "androidx.core:core-ktx:${Versions.CORE}"
    }

    object Test {
        const val JUNIT = "androidx.test.ext:junit:${Versions.JUNIT}"
    }

    object AndroidTest {
        const val ESPRESSO_CORE = "androidx.test.espresso:espresso-core:${Versions.ESPRESSO_CORE}"
    }
}

위 활동을 마쳤다면 마무리로 모든 .gradle 파일을 .gradle.kts 로 변환해주어야 한다. (Kotlin DSL 파일의 확장자는 .kts 이기 때문)

setting.gradle > setting.gradle.kts로 변경

setting.gradle은 gradle 프로젝트를 세팅하기 위한 정보가 담겨있다. 이 gradle 파일을 .kts를 추가하여 변경해준다.

위와 같이 변경하였다면 내부 코드도 당연히 변경해주어야 한다.

변경 전

rootProject.name = "VelogProject"
include ':app'

변경 후

rootProject.name = "VelogProject"
include(":app")

Kotlin 에서는 ' 대신 "로 사용한다.


build.gradle(:Project) > build.gradle.kts로 변경

다음 build.gradle(project) 파일을 위와 같이 .kts를 추가하여 변경해준다.

그 다음 마찬가지로 내부 코드를 수정해주어야 한다.

변경 후

buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:${Versions.GRADLE}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.KOTLIN}")
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

tasks.register("clean", Delete::class) {
    delete(rootProject.buildDir)
}

build.gradle(Module) > build.gradle.kts로 변경

모듈 수준의 build.gradle 파일에는 '가 많기 때문에 모두 "로 변경해주어야 한다.

plugin 변경 후

plugins {
    id("com.android.application")
    kotlin("android")
    kotlin("android.extensions")
}

android 블록 변경 후
안드로이드 블록은 함수 또는 내부 프로퍼티로 짜여있으므로 하나씩 잘 변경해주어야 한다.

android {
    compileSdk = AppConfig.compileSdk
    buildToolsVersion = AppConfig.buildToolsVersion
    buildFeatures {
        dataBinding = true
    }

    defaultConfig {
        applicationId = "com.example.example"
        minSdk = AppConfig.minSdk
        targetSdk = AppConfig.targetSdk
        versionCode = AppConfig.versionCode
        versionName = AppConfig.versionName

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = AppConfig.jvmTarget
    }
}

dependencies 블록 변경 후

dependencies {
    implementation(Dependencies.KOTLIN_STDLIB)

    // AndroidX
    implementation(Libraries.AndroidX.APP_COMPAT)
    implementation(Libraries.AndroidX.MATERIAL)
    implementation(Libraries.AndroidX.CONSTRAINT_LAYOUT)

    // KTX
    implementation(Libraries.KTX.CORE)

    // TEST
    testImplementation(Libraries.Test.JUNIT)

    // AndroidTest
    androidTestImplementation(Libraries.AndroidTest.ESPRESSO_CORE)


    implementation(Dependencies.CARD_VIEW)
    implementation(Dependencies.NAVIGATION_FRAGMENT)
    implementation(Dependencies.NAVIGATION_UI)
    implementation(Dependencies.GLIDE)
    implementation(Dependencies.GLIDE_COMPILER)
    implementation(Dependencies.RETROFIT)
    implementation(Dependencies.CONVERTER_GSON)
    implementation(Dependencies.GSON)
    implementation(Dependencies.OKHTTP)
    implementation(Dependencies.LOGGING_INTERCEPTOR)
    implementation(Dependencies.ROOM)
    implementation(Dependencies.LIFECYCLE_VIEWMODEL)
    implementation(Dependencies.LIFECYCLE_LIVEDATA)
}

참고
https://medium.com/android-dev-hacks/kotlin-dsl-gradle-scripts-in-android-made-easy-b8e2991e2ba

profile
공부가 조은 안드로이드 개발자

0개의 댓글