이번 토이프로젝트에서 처음으로 멀티모듈을 적용해보기로 다짐한 후,
여러 관련 post를 읽어보고 android의 now in android 프로젝트 코드를 전체적으로 분석해보면서
어떻게 제 프로젝트에 적용하였는지 정리해보고자 합니다. 🤗
혼자 공부해서 혼자 해본거라 틀린 점이 있을 수 있어요!
만약 있다면 꼭 댓글로 말씀 부탁드립니다. 🙏
1. 프로젝트 구조 기획
사실 모듈 자체를 생성하는 것은 안드로이드 스튜디오를 사용한다면 어렵지 않습니다.
하지만 기존 single module 개발에서와 마찬가지로 Layer들을 확실히 나눈 상태에서 멀티모듈을 만들어 보고 싶었어요. 🔥
그래서 프로젝트 개발을 본격적으로 시작하기 전에 어떠한 모듈들을 만들고
어떤 의존관계를 가질 지 기획하는 시간을 가지기로 했습니다.
이때 많이 참고한 것이 바로 Android NowinAndroid Github 문서에 있는 프로젝트 구조도였습니다.
👈🏻 nowinandroid | 토이 프로젝트 구조 기획 👉🏻
GitHub - android/nowinandroid: A fully functional Android app built entirely with Kotlin and Jetpack Compose
A fully functional Android app built entirely with Kotlin and Jetpack Compose - GitHub - android/nowinandroid: A fully functional Android app built entirely with Kotlin and Jetpack Compose
github.com
이제 기획을 마무리하였으니, 실제로 모듈을 생성해보겠습니다.
2. 모듈 생성
모듈 생성은 간단해요. 🤗
대신 아래와 같이 settings.gradle에 생성한 모듈을 추가(include)해줄 필요가 있습니다.
하지만 모듈을 여러 개 생성하다보니 신경쓰이는 부분이 생기게 되었습니다. 🤔🤔
바로 각 모듈의 build.gradle과 dependencies들이 너무 중복된다는 점이었어요.
3. Version Catalog
가장 먼저 중복되는 dependency들을 한 곳에서 관리해주기 위해 version catalog를 사용하도록 하겠습니다.
🌹 라이브러리들의 버전을 변경할 때도 한 곳에서만 변경하면 되기 때문에 운영에도 유용합니다.
Version Catalog인 libs.versions.toml 파일은 gradle 디렉토리 하위에 위치하게 됩니다.
이전에는 이 version catalog 파일 또한 settings.gradle에서 추가해주어야 했지만,
gradle 7.4 부터는 아무런 추가 코드 없이 바로 사용할 수 있게 되었다고 합니다. 😌👍🏻
또한 관련있는 라이브러리들은 bundle로 묶어 한 번에 추가할 수 있도록 해 두었어요.
이렇게 정의한 라이브러리와 bundle은 아래와 같이 사용할 수 있습니다. 🤗
지금까지 라이브러리 버전 관리는 한 곳에서 할 수 있도록 해주는 version catalog에 대해 알아보았습니다.
하지만 모듈별로 가지고 있는 여러 설정(Configuration)도 마찬가지로 하나로 묶어 한 곳에서 관리해주고 싶습니다.ㅎㅎ📌
어떻게 하면 이를 실현할 수 있을까 자료를 찾아보고 nowinandroid github를 더 세세히 분석해본 결과 nowinandroid와 동일하게 build-logic을 사용해보기로 하였습니다. 🔥
4. build-logic
이곳에서 할 일은 바로 각 모듈에서 사용할 공통 설정들을 관리할 수 있는 custom plugin을 만드는 것입니다.
build-logic은 별도의 프로젝트로 만들어두고, settings.gradle에서 가져와 사용할 수 있도록 해 두었습니다.
👇🏻 요렇게!
build-logic에서는 본 프로젝트와 다르게 app module이 아닌, convention이란 이름의 모듈만 만들어 사용하도록 하겠습니다.
따라서
- convention 모듈 생성
- build-logic의 settings.gradle에 추가
위 작업을 순차적으로 해주면 준비 완료입니다. 😆
제가 만든 plugin은 총 6개입니다.
- AndroidApplicationConventionPlugin
- AndroidApplicationComposeConventionPlugin
- AndroidFeatureConventionPlugin
- AndroidLibraryComposeConventionPlugin
- AndroidLibraryConventionPlugin
- AndroidHiltConventionPlugin
🌹 이렇게 만들어진 plugin은 사용할 곳에서 필요한 plugin들만 가져와 조립을 하듯이 사용할 수 있다는 장점이 있는거 같아요.
예를 들어, repository 코드가 위치하는 core:data에서는
- 기본 library convention
- hilt
위 2가지 기능(?)이 필요하기 때문에
이런 식으로 plugin을 지정해줄 수 있습니다. 😌
그렇다면 plugin은 어떻게 작성할 수 있을까요?
plugin은 Plugin interface를 구현한 클래스로 정의할 수 있어요.
public interface Plugin<T> {
/**
* Apply this plugin to the given target object.
*
* @param target The target object
*/
void apply(T target);
}
apply 메서드를 오버라이드 하여 plugin을 사용하는 대상(target)을 가져와 여러 설정을 한 곳에서 추가해줄 수 있습니다.
대표적으로 app 모듈에서 사용하는 AndroidApplicationConventionPlugin 코드를 확인해보도록 하겠습니다.
👈🏻 AndroidApplicationConventionPlugin으로 작성한 설정 | 프로젝트를 생성하면 기본으로 추가되는 build.gradle(:app) 👉🏻
위 이미지에서 보면 알 수 있듯이, 원래 build.gradle에서의 설정과 거의 동일하게 적용되는 것을 알 수 있습니다.
다른 점이라 하면 여러 module에서 재활용할 수 있다는 점이예요. 👍🏻
또 다른 예로 feature 모듈들에서 공통적으로 사용되는 AndroidFeatureConventionPlugin을 보면
그저 설정들 뿐만 아니라 공통으로 사용되는 모듈과 라이브러리들도 추가할 수 있습니다.
이제 이렇게 만든 plugin들을 실제 사용해 볼 차례입니다.
먼저 만들어둔 plugin들을 사용할 수 있도록 등록(register)해줄 필요가 있습니다.
👇🏻 요렇게 convention의 build.gradle 내에
id는 plugin의 id, implementationClass는 이름 그대로 plugin을 구현한 class를 말합니다.
결과적으로는 이렇게 사용할 수 있습니다. 😆
🌹 이렇게 custom plugin을 사용하게 된다면 공통 코드를 많이 줄일 수 있다는 장점이 있는거 같아요.
실제로 feature:home module의 build.gradle은 아래와 같이 간단하게 작성할 수 있었습니다. 👏🏻👏🏻👏🏻
5. 결론
멀티 모듈은 처음이라 처음은 구조를 잡고 공통코드를 제거하는데에만 전체 프로젝트 기간에 반을 쓰게 되었어요.ㅎㅎ 😭
하지만 결과물이 생각보다 만족스러워 의미있는 시간이기도 했습니다. 😆
5.1 최종 프로젝트 구조
앞으로는 gradle과 build에 대해 추가적인 학습을 진행한 후, 효율적인 빌드 작업을 수행하는 방법에 대해 고민해보려고 해요.
멀티모듈의 장점이 빠른 빌드 시간인데 이를 완벽히 제공하고 있는지 의문이 들었기 때문입니다.
추후에 좀 더 발전한 지식으로 돌아오도록 하겠습니다! 🔥
감사합니다.
'기록 > 회고록' 카테고리의 다른 글
[2024] 부터 시작하는 올해 뭘 했을까? 😆 (0) | 2024.11.08 |
---|---|
[하루네컷] Designsystem에 맞게 Core Component 만들어보기 (0) | 2023.04.04 |
[Android] Github CI/CD를 이용해 Firebase App Distribution까지! (0) | 2023.04.02 |
[우테캠] 2차 팀별 과제 회고록 (2) | 2022.07.22 |
처음 써보는 회고록👍🏻 가봤슈 프로젝트 (2) | 2022.06.30 |