๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/๊ธฐํƒ€

[Gradle] Type-safe Project Accessors ๋„์ž… ๋ฐฐ๊ฒฝ ๋ฐ ์‚ฌ์šฉ๋ฒ•

interfacer_han 2025. 12. 30. 21:02

#1 ๊ธฐ์กด์˜ ๋ชจ๋“ˆ ํ˜ธ์ถœ ๋ฐฉ์‹

// in build.gradle

plugins {
    ...
}

android {
    ...
}

dependencies {

    ...
    implementation(project(":datastore"))
    implementation(project(":designsystem"))
}

์ด ๋ฐฉ์‹์ด ๋น„ํšจ์œจ์ ์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

  • ๋ชจ๋“ˆ ์ด๋ฆ„์˜ ์ŠคํŽ ๋ง์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ธฐ์–ตํ•ด์•ผ ํ•˜๊ณ , ๋ชจ๋“ˆ ์ด๋ฆ„์„ ๋ณ€๊ฒฝ์ด๋ผ๋„ ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๋‚ด ๋ชจ๋“  implementation() ๋ฌธ์„ ์ฐพ์•„๋‹ค๋‹ˆ๋ฉฐ ์ˆ˜๋™ ๋ณ€๊ฒฝํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ๊ฒŒ๋‹ค๊ฐ€ ์‚ฌ๋žŒ์˜ ์ˆ˜๋™ ๋ณ€๊ฒฝ์€ ์ผ๋ถ€ ์ฝ”๋“œ์˜ ๋ˆ„๋ฝ ๊ฐ€๋Šฅ์„ฑ๊นŒ์ง€ ์žˆ๋‹ค.
  • ์ž˜๋ชป๋œ ๋ชจ๋“ˆ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ build.gradle์˜ DSL(Gradle DSL)๋‹จ์—์„œ ์žก์•„๋‚ด์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์—, Gradle์˜ ๋นŒ๋“œ๊ฐ€ ์‹œ์ž‘๋˜๊ณ  ๋‚˜์„œ์•ผ ๋’ค๋Šฆ๊ฒŒ ์—๋Ÿฌ๋ฅผ ์ธ์ง€ํ•˜๊ฒŒ ๋œ๋‹ค.

 

#2 Type-safe Project Accessors

 

Declaring Dependencies

build.gradle.kts plugins { `java-library` } repositories { mavenCentral() } dependencies { implementation("org.ow2.asm:asm:7.1") { because("we require a JDK 9 compatible bytecode generator") } } build.gradle plugins { id 'java-library' } repositories { mav

docs.gradle.org

Type-safe Project Accessors๋Š” Gradle 7.0๋ถ€ํ„ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Gradle์˜ ๊ธฐ๋Šฅ์ด๋‹ค. #1์˜ ๋น„ํšจ์œจ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…๋˜์—ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ ์–ด๋–ค ๊ธฐ๋Šฅ์ธ์ง€๋Š” ์•„๋ž˜์— ์žˆ๋Š” ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ

// in build.gradle

// ๊ธฐ์กด ๋ฐฉ์‹
dependencies {
    implementation(project(":utils"))
    implementation(project(":api"))
}

---
// in build.gradle

// Type-safe Project Accessors๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹
dependencies {
    implementation(projects.utils)
    implementation(projects.api)
}

์ด ๋ฐฉ์‹์ด ํšจ์œจ์ ์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

  • ๋ชจ๋“ˆ ์ด๋ฆ„์˜ ์ŠคํŽ ๋ง์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ธฐ์–ตํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ๋ชจ๋“ˆ ์ด๋ฆ„ ๋ณ€๊ฒฝ ์‹œ ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ผ๊ด„(์ž๋™)์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜๊ธฐ์—, ์ด๋ฆ„ ๋ณ€๊ฒฝ ์ž‘์—…์ด ์ผ๋ถ€ ์ฝ”๋“œ์—์„œ ๋ˆ„๋ฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด 0์œผ๋กœ ์ˆ˜๋ ดํ•œ๋‹ค.
  • ์ž˜๋ชป๋œ ๋ชจ๋“ˆ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ, Kotlin DSL์ธ ๊ฒฝ์šฐ Kotlin ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฆ‰์‹œ "Unresolved reference 'sampleIncorrectModuleName'."๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•ด ์ค€๋‹ค (์‹œ๊ฐ„ ์ ˆ์•ฝ).

 

์—ฌ๋‹ด์œผ๋กœ Groovy๋Š” ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ด๊ธฐ์—, Groovy DSL์„ ์“ธ ๋•Œ๋Š” (Kotlin DSL์„ ์“ธ ๋•Œ์ฒ˜๋Ÿผ) ์˜ค์ž…๋ ฅ๋œ ๋ชจ๋“ˆ ์ด๋ฆ„์„ '์ฆ‰์‹œ' ์žก์•„์ฃผ์ง€๋Š” ๋ชปํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

 

#2-1 ํ™œ์„ฑํ™” ๋ฐฉ๋ฒ•

Type-safe Project Accessors๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด setting.gradle์—,

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ setting.gradle์˜ ์–ด๋А ๋ถ€๋ถ„์— ์œ„์น˜์‹œ์ผœ์•ผํ•˜๋Š”์ง€๋Š” (๊ณต์‹ ๋ฌธ์„œ์—) ๋ช…ํ™•ํžˆ ๋‚˜์™€ ์žˆ์ง€ ์•Š์•˜๋‹ค.

 

๊ทธ๋ž˜์„œ,

// in setting.gradle (of Now in Android)

/*
 * Copyright 2021 The Android Open Source Project
 * ...
 */

pluginManagement {
    ...
}

dependencyResolutionManagement {
    ...
}
rootProject.name = "nowinandroid"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include(":app")
include(":app-nia-catalog")
include(":benchmarks")
include(":core:analytics")
include(":core:common")
include(":core:data")
...

check(JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
    ...
}

Now in Android ์†Œ์Šค ์ฝ”๋“œ์˜ setting.gradle๋ฅผ ๋ณด๊ณ  ๊ฐ์„ ์žก์•˜๋‹ค. ์œ„์˜ ์ฝ”๋“œ์™€ ๊ฐ™์€ ์œ„์น˜์— ๋‘๋ฉด ๋  ๊ฒƒ์ด๋‹ค.

 

#2-2 Accessor ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„ ๊ทœ์น™

๊ธฐ์กด ๋ฐฉ์‹ → Type-safe Project Accessors
:commons:utils:some:lib → projects.commons.utils.some.lib
:some-lib → projects.someLib
:some_lib → projects.someLib

๋ชจ๋“ˆ ์ด๋ฆ„์— ์žˆ๋Š” ์ผ€๋ฐฅ ์ผ€์ด์Šค(some-lib)์™€ ์Šค๋„ค์ดํฌ ์ผ€์ด์Šค(some_lib)๋Š” ์นด๋ฉœ ์ผ€์ด์Šค(someLib)๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

 

#3 ์‹ค์‚ฌ์šฉ ์˜ˆ์‹œ

์‹ค์ œ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ์ฝ”๋“œ์— ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค.

 

Type-safe Project Accessors ๋ฏธ์‚ฌ์šฉ ์ฝ”๋“œ

// in build.gradle

plugins {
    ...
}

android {
    ...
}

dependencies {

    ...
    implementation(project(":datastore"))
    implementation(project(":designsystem"))
}

#1์— ์žˆ๋Š” ์ฝ”๋“œ๋‹ค.

 

Type-safe Project Accessors ํ™œ์„ฑํ™”

pluginManagement {
    ...
}

dependencyResolutionManagement {
    ...
}
rootProject.name = "swemo"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include(":app")
include(":database")
include(":designsystem")
...

 

Type-safe Project Accessors๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

// in build.gradle

plugins {
    ...
}

android {
    ...
}

dependencies {

    ...
    implementation(projects.datastore)
    implementation(projects.designsystem)
}

 

์ฐธ๊ณ