들어가며
안녕하세요~ 대부분의 프로젝트에서는 multi module 을 고려하여 구성하시는 경우들이 많은데요.
multi module 로 나누어 각 모듈의 역할을 분리하고, 재사용성을 증진시키기 위해 multi module 을 활용하고 계시더라구요
그런데 multi module 로 나누게 되면, 가장 큰 문제점으로 다가오는 것이 바로 build 설정들이 중복되서 관리되는 것이 참 아쉬운 부분입니다.
이러한 아쉬운 점을 해결하기 위해 gradle 에서는 buildSrc 혹은 build-logic 이라는 모듈을 기반으로 중복되는 build 설정들을 하나로 일원화시킬 수 있게 제공하는데요.
한번 알아보도록 해보겠습니다~!
Multi Project Build basic
전체적인 gradle 의 overview 는 위와 같습니다.
project 에 설정된 script 를 input 값으로 받고, plugins 와 dependencies 를 가져와 task 순서에 따라 build flow 를 만들게 되죠.
그래서 최종적인 결과물은 jar file 이 나오거나 다양한 형태의 file 들이 만들어질 수 있게 됩니다.
여기서 그림에서 buildSrc 라는 박스가 파란색으로 되어 잇는데요. buildSrc 에 대해 조금 더 알아봅시다
buildSrc
buildSrc 의 역할은 각 project 에서 사용되는 build script 들을 재사용이 가능한 logic 을 제공하는 것이 역할입니다.
buildSrc 를 만듬으로써 얻게 되는 이점은 아래와 같은데요
- 재사용 가능한 build logic: 공통화된 로직을 추출하여 만들었으니 재사용이 가능해집니다.
- Main build 와의 격리: 각 프로젝트별로 build 시에 원하는 build logic 을 적용하고 main build 에 포함 유무를 유동적으로 할 수 있게 됩니다.
- compilation 자동화: buildSrc 의 compile 우선순위가 항상 높게 되고, 다양한 스크립트를 만들어 자동화할 수 있습니다.
- 쉬운 테스트: Custom build logic 만 만들어서 테스트가 가능하기에 project 를 만들고 테스트할 필요가 없습니다.
- Gradle plugin 개발: Plugin 을 만들때 buildSrc 에 위치시켜 원하는 project 에 적용할 수 있습니다.
쉽게 요약하면, 개발자가 원하는대로 build script 들을 만들고 운영할 수 있게 된다 라고 이해하면 되겠네요.
build-logic
그렇다면 buildSrc 는 이해했는데 build-logic 은 무엇인가요?
buildSrc 는 subproject 로 취급되어 root project 에 속한 project 에서 build script 을 가져와 사용할 수 있게 되지만,
build-logic build directory 로 취급되어 root project 에 속한 project 에서 build script 을 가져와 사용할 수 있습니다.
build-logic 과 같이 운영하는 것을 composite build 라고 gradle 공식문서에서는 명칭을 붙이고 있네요
Composite Builds, also referred to as included builds, are best for sharing logic between builds (not subprojects) or isolating access to shared build logic (i.e., convention plugins).
위 내용은 gradle 공식문서에 있는 내용인데요.
Composite build 의 핵심은 바로 build logic 을 격리하는 것에 있다고 볼 수 있네요.
즉, buildSrc 와 build-logic 의 차이는 특정 project 빌드시에 사용되지 않는 build script 마저 빌드에 포함할 것이냐 안할 것이냐 로 이해하면 됩니다.
어떤 전략을 선택할 것인지는 개발자의 취향에 따라 선택할 문제인데요.
제 개인적인 취향으로는 build-logic 을 조금 더 좋아합니다.
왜냐하면, 프로젝트가 커지면 커질수록 build script 또한 많아질 것이고, 이를 build 단계에서부터 확실하게 격리(isolation) 해야 조금 더 성능적인 우위가 있다고 생각되었기 때문입니다.
With version catalog?
본래 Multi project 에서 pre-compiled-script 는 gradle 에서 version 을 관리하는 version catalog 와도 충분히 호환되게 기능을 제공하는 것이 목적이었습니다.
그렇지만, pre-compiled-script 에서 version catalog 에서 정의한 version 을 가져와 참조할 수 없도록 되어 있는 것이 조금 아쉬운 상황이네요.
저처럼 많은 사람들도 불편함을 느꼈고, 역시나 이를 해결하기 위한 우회책들이 아래 issue link 에 기입되어 있습니다.
다만 이미 많은 사람들이 관심을 갖고 있으니 언제쯤 해결될날이 오지 않을까요? ㅎㅎ
version catalog 를 사용하고 계신다면, 아래 링크 참고하여 custom code 를 추가적으로 작성해주시거나, 혹은 한계치를 인정하고 제공된 기능으로만 사용하는 전략을 채택해주시면 됩니다.
https://github.com/gradle/gradle/issues/15383
Sample Repository
직접 구현한 sample repository 는 아래와 같습니다~! 아래와 같은 tree 형태로 구성되어 있죠
- build-logic
- build.gradle.kts
- src/main/kotlin
- project-conventions.gradle.kts
- kotlin-conventions.gradle.kts
- spring-conventions.gradle.kts
- jib-conventions.gradle.kts
- order-application
- build.gradle.kts
- product-application
- build.gradle.kts
- settings.gradle.kts
제가 sample 로 드리는 것은 언제나 예시일 뿐이며,
각 프로젝트 상황에 맞추어 재사용성을 극대화하기 위해 gradle.kts 의 단위를 더 작게 가져가주셔도 됩니다~!
https://github.com/huisam/spring-observability
요약
오늘의 게시글을 요약하면 아래와 같습니다~! ㅎㅎ
- Gradle multi module 구축시 build script 를 재사용할 수 있는 방안을 적용하는 것이 좋다.
- build script 를 재사용할 수 있는 방안으로는 buildSrc(subproject) 와 build-logic(composite build) 방식이 있다.
- 개인의 취향에 따라 적절한 솔루션을 채택하여 gradle 에서 build script 를 멋지게 관리해보자!
참고
https://docs.gradle.org/current/userguide/intro_multi_project_builds.html
https://docs.gradle.org/current/userguide/sharing_build_logic_between_subprojects.html
'Developer > Spring' 카테고리의 다른 글
Spring Validation 의 종류와 동작하는 방식에 대해 알아보자 (0) | 2025.01.01 |
---|---|
[Test] Junit5 에서 제공하는 Tag 에 대해 알아보자 (0) | 2024.06.20 |
Spring Boot API server 성능 테스트(performance test)를 해보자(with python locust) (0) | 2024.02.12 |
[JPA] Hibernate 에서 지원하는 Id generator 에 대해 알아보자 (1) | 2023.12.17 |
Micrometer Tracing 에 대해 알아보자(a.k.a. spring cloud sleuth) (0) | 2023.10.28 |