들어가며
앱이 모듈화되는 경우에는 각 모듈을 로컬 라이브러리로 참조하여 별도로 모듈의 버전 관리 없이 앱의 버전만 관리하여 APK 파일을 배포가 가능하다. 하지만 SDK의 경우 각각의 모듈에 대해서 버전을 모두 명시 후에 배포까지 다 해줘야 하는 이슈가 있다. 이 문서에서는 멀티 모듈 앱과 멀티 모듈 SDK의 차이에 대해서 간단히 설명하고 멀티 모듈 SDK에서는 왜 버전을 각각 관리해줘야 하는지 설명한다.
멀티 모듈 앱
구조도
멀티 모듈 앱은 다음과 같은 구조로 되어 있다.
위와 같이 앱의 경우 빌드되는 결과물인 APK 파일 안에 앱에 필요한 모든 코드가 다 들어있다. 즉, 별도로 각 모듈을 배포할 필요가 없고 APK 파일 안에 모든 모듈 데이터가 포함된다.
참조 모듈과 버전
앱의 경우 APK에 모든 필요한 정보가 병합되어 빌드되기 때문에, 멀티 모듈로 구성되더라도 앱 자체에 대해서만 버전 관리를 하면 모듈 간의 충돌이 발생하지 않는다.
멀티 모듈 SDK
구조도
멀티 모듈 SDK는 다음과 같은 구조로 되어 있다.
이처럼 SDK의 경우 빌드 결과물인 AAR 파일 내부에 자기 자신의 코드만 갖고 있고, 참조하는 모듈의 코드를 직접 갖고 있지 않다. 대신에 AAR은 POM 파일을 포함하고 있으며 해당 파일 안에 참조하는 모듈의 이름, 버전 등을 명시한다.
이렇게 빌드된 AAR 파일은 다음에 앱을 빌드할 때 그래들의 의존성 정책에 따라 최종적으로 어떤 모듈에 어떤 버전을 쓸 것인지 결정된다.
따라서 SDK의 경우 멀티 모듈로 구성 된다면 참조하고 있는 각 모듈을 모두 버전에 맞게 배포를 해줘야 앱의 빌드 시점에 해당 모듈을 찾아서 빌드가 가능하다.
참조 모듈과 버전
그래들 멀티 프로젝트를 구성하다 보면 모듈을 참조하는 방법은 보통 다음 2가지를 사용한다. (참고 문서)
원격 바이너리 참조
implementation 'com.buzzvil:my-module:1.2.3'
// 저장소에서 com.buzzvil 그룹의 my-module 모듈 중 1.2.3 버전에 해당하는 바이너리를 찾아서 연동
원격 바이너리 참조의 경우 참조하는 모듈의 바이너리 파일을 설정한 저장소에서 찾아서 연동한다. 이때 해당 모듈의 그룹, 이름, 버전 정보를 정확히 기입을 해서 참조를 하므로 스크립트 상으로 어떤 모듈을 참조하고 있는지 명확히 알 수 있다. 단, 해당 모듈이 저장소에 배포된 상태여야 빌드가 가능하다.
로컬 라이브러리 모듈 참조
implementation project(':my-module')
// 프로젝트에서 my-module 모듈을 찾아서 연동
로컬 라이브러리 모듈 참조의 경우 참조하는 모듈을 프로젝트 로컬 라이브러리 모듈에서 찾아서 연동한다. 이때 해당 모듈의 세부 정보를 기입하지는 않는다.
그렇다면 이때 SDK 파일을 빌드하면 해당 모듈의 이름과 버전 정보는 어떻게 기록되는가?
로컬 라이브러리 참조 모듈이 포함된 SDK 파일을 빌드할 경우에는, 빌드 툴이 빌드 시점에 해당 모듈 프로젝트에서 직접 모듈에 대한 정보를 추출해서 POM 파일을 생성해준다. 따라서 평소에는 별도의 버전 정보를 참조하고 있지 않고, SDK를 빌드하는 시점에 해당 모듈 프로젝트에 설정된 버전 정보를 바탕으로 AAR 파일을 생성한다.
개발 주의 사항
멀티 모듈로 구성된 SDK를 배포할 때 주의해야 할 사항을 설명한다.
첫째, 배포 시점에 모든 참조 모듈을 함께 배포해야 한다.
SDK의 결과물인 AAR 파일에는 참조하는 모듈의 코드가 포함되지 않는다. 따라서 SDK 배포 시에는 참조하고 있는 모든 모듈이 배포되어야 한다.
둘째, 배포 시점에 모든 모듈의 버전이 고유해야 한다.
POM 파일에 참조하고 있는 모듈이 어떤 것인지 정해지는 것은 배포할 AAR 파일을 빌드하는 시점이다. 일반적으로는 빈트레이 업로드를 할 때 SDK가 빌드되며 버전 정보가 정해진다. 즉, 이 시점에는 모든 참조 모듈들의 버전이 정확히 관리되어야 한다. 만약 1.0.0으로 미리 배포된 후 코드 수정이 있었지만 아직 모듈의 버전 정보가 1.0.0으로 되어 있다면 AAR 파일에는 해당 모듈이 1.0.0으로 기록될 것이고, SDK 사용자는 의도하지 않은 버전의 모듈을 참조하게 될 것이다.
각각의 모듈의 버전을 어떻게 관리할 것인지는 모노리포 개발 가이드를 참조한다.
셋째, 다른 SDK 간에 모듈 충돌이 일어날 수 있음을 인지한다.
만약 여러 SDK가 동일한 모듈을 참조하고 있고 해당 SDK들이 하나의 앱에서 빌드되고 있다면, 모듈간 충돌에 대해 고민해봐야 한다.
위와 같이 각각의 SDK가 같은 모듈의 서로 다른 버전을 참조하고 있으면 최종적으로 앱이 빌드되는 시점에 모듈의 어떤 버전을 사용할지 결정이 된다. 이 경우 한쪽의 SDK에서 다른 버전의 모듈을 사용하게 되기 때문에 충돌이 일어날 수 있다. 이를 잘 해결하기 위해서 기본적으로 개발자는 모듈의 하위호환에 대해서 인지하고 개발을 진행해야 하고, 연동자는 그래들의 버전 해석 정책을 이용해서 어떤 버전을 사용할지 제어해야 한다.