본문 바로가기

iOS

[iOS] 모듈화 가보자고..🚀(1) - 모듈화하게 된 배경과 진행 방법

안녕하세요👋 오랜만에 글을 쓰네요.
글쓰기 귀찮아했지만 일들이 바빠서 못적고 있었다는 핑계를 둘러대봅니다..
회사에서 요즘 모듈화와 관련된 내용을 많이 느리지만 천천히 반영해가고 있는데요, 그 내용을 하나씩 정리해 보고자 합니다.
아직 모듈화가 많이 진행된 상황은 아니고 아직도 초반이라고 생각합니다. 모듈화를 끝내고 내용을 정리해서 글을 작성하는 방법도 생각은 해봤지만 진척도가 있을 때마다 조금씩 글을 적는 것이 지금 상황에서 겪고 있는 문제나 해결 방법을 더 잘 기억하고 작성할 수 있다고 생각해서 하나씩 적어보려고 합니다.
이번에는 모듈화를 하게 된 배경과 어떻게 진행할지 작성한 방법에 대한 내용을 정리합니다.
이 시리즈 포스트가 몇 장에 끝날지는 저도 궁금하네요 🤔


왜 모듈화 생각을 시작하게 되었을까?

1. 입사했을 때의 상황

이제 프렌트립에 입사한지 1년이 조금 넘어가는 상황이고 회사에 처음 입사했을 때, 회사의 프로젝트는 단 하나의 큰 프로젝트로만 구성되어 있었습니다. 1~2명의 개발자가 해당 프로젝트를 지속적으로 개발하고 운영해나갈 상황에서는 큰 문제가 없는 상황입니다. 하지만 개발자가 앞으로도 계속 1~2명일 것이란 보장이 없어서(물론 더 작아질 수도 있지만..) 더 많은 개발자와 함께 협업하기 위해서는 큰 프로젝트를 쪼개야 하는 상황이었습니다. 더 많은 개발자와 협업하기 위해 왜 쪼개나? 생각이 들 텐데요!, 프로젝트를 모듈화 진행하면 모듈 안에서의 코드 응집도는 올라가고 모듈 간의 결합도는 낮아지므로 모듈 안에서 개발자가 의존성 없이 개발을 하기 쉬워집니다. 이런 문제를 해결하기 위해 모듈화를 생각하게 되었습니다.

2. 코드의 재사용성을 높이고 싶다.⤴️

회사에서 호스트들을 위한 호스트앱 신규 프로젝트를 시작했습니다. 호스트앱은 프립에서 호스트 분들이 사용할 수 있는 앱으로 자신의 상품 관리를 할 수 있는 서비스입니다. 호스트앱은 프립앱의 UI 컴포넌트라든지, 베이스 코드 등 일부 코드들을 동일하게 사용합니다. 동일한 코드를 사용하기 때문에 모듈화를 떠올렸습니다. 프립앱과 호스트앱에서 동일하게 사용하는 코드들을 모듈화시킨다면 호스트앱에는 그 모듈을 가져다 쓰기만 하면 호스트앱에서 중복 코드를 또 한 번 작성할 필요 없이 편리하게 개발할 수 있을 것이라 생각했습니다.

3. 빌드 타임을 줄이고 싶다🚀

하나의 큰 프로젝트를 빌드 하는데 소요되는 시간이 제 자신이 느끼기에는 너무나도 긴 시간이었습니다. 클린 빌드를 실행하면 Intel 맥에서 15분 ~ 16분 정도 소요되었습니다. 빌드 시간이 오래 걸리는 이유로는 pod library를 많이 사용중이기도 하고, GraphQL 스키마 받아와서 컴파일 하기도 하고, 프로젝트 볼륨 자체가 큰 것등 여러 요소들이 존재했습니다. 빌드 타임이 이렇게 오래 걸리면서 낭비되는 시간이 생각보다 많아서 모듈화를 생각하게 되었습니다.
(물론 지금은 M1맥으로 변경하고, CocoaPod Cache를 적용하고, 일부 모듈화가 진행되어서 많이 줄어든 상황입니다.)


모듈화를 어떻게 할까?

1. 생각하면서 나왔던 모듈 아키텍처들

1-1. 공통 모듈 + 탭별로 모듈 분리

공통 모듈 + 탭별로 모듈 분리

첫 번째로 생각한 구조는 여러 프로젝트에서 사용할 수 있는 공통 모듈(Base, FDS)과 탭별로 모듈을 나누는 방법입니다.
이렇게 생각한 이유는 먼저 다수의 프로젝트에서 공용으로 사용할 수 있는 코드들은 무조건 모듈화 시키자는 생각이었습니다.
Base모듈을 프로젝트 전반적에서 사용할 수 있는 베이스 코드, 유틸성 함수가 들어있습니다. FDSFrip Design System의 약자로 프립에서 사용하는 디자인 시스템 컴포넌트들입니다. 디자인 시스템 컴포넌트들도 베이스 코드와 마찬가지로 모든 프로젝트에서 사용하기 때문에 별도의 모듈화 시키자고 생각했습니다.

그리고 나머지 모듈들은 탭별로 나누어보는 방법을 생각했습니다. 저는 개인적으로 도메인 단위로 나누는 것을 선호합니다. 프로젝트 디렉토리 구조와 유저가 앱에서 접근할 수 있는 구조를 동일하게 설정하면 프로젝트 구조를 완벽히 모르더라도 쉽게 파일을 찾아갈 수 있기 때문입니다. 그래서 현재 프립 앱에서 하단에 존재하는 탭별로 나누고 그 탭 혹은 화면에 해당하는 코드들이 해당 모듈에 들어가는 구조를 생각했습니다. 또한 현재 구조상 탭으로 나누는 것이 모듈별 볼륨이 적절하다고 생각했습니다.
이런 구조로 진행했을 경우 특정 피처를 개발할 때 하나의 모듈 안에서 다른 모듈에 영향을 끼치지 않고 뷰, 로직, API 개발을 진행할 수 있습니다.




1-2. 공통 모듈 + 기능에 따른 모듈 분리

공통 모듈 + 기능에 따른 모듈 분리

두 번째로 생각한 구조는 첫 번째 구조와 동일하게 공통으로 사용할 수 있는 모듈은 그대로 두고 기능에 따라 모듈을 분리하는 구조입니다.
이런 구조도 깔끔하다고 생각은 했지만 새로운 피처를 개발한다고 가정할 때, 대부분의 모듈에 추가/변경 작업이 일어나기 때문에 협업으로 진행하기에는 조금 어렵다는 생각을 했습니다.
두 개 구조의 장/단점을 비교한 결과 첫 번째 구조로 진행하기로 결정했습니다.

2. 어떤 순서로 모듈화 작업을 진행할까?

2-1. 공통 코드들 의존성 제거 및 모듈화 진행

먼저 모든 프로젝트에서 공통으로 사용할 수 있는 코드들을 분리하는 작업을 진행하여 Base 모듈과 FDS 모듈을 생성합니다. Base 코드들 (BaseView, BaseViewController, ...)과 유틸성 함수들을 새로운 Base 모듈을 만들어 이동시키고 메인 프로젝트에서는 새로 만든 Base 모듈의 함수를 호출하도록 수정합니다. 해당 과정은 모듈에 들어가는 코드의 양이 다른 모듈에 비해 상대적으로 적기도 하고 기본 구조와 관련된 코드들이다 보니 다른 과정들 보다 의존성 제거를 하여 이관하기 비교적 쉽다고 생각합니다.
FDS 디자인 시스템 모듈에서는 디자인 가이드에 정의되어 있는 UI 컴포넌트들과 디자인 리소스들을 정의해놓습니다. 메인 프로젝트에서 FDS 모듈을 추가하면 FDS에 정의된 컴포넌트들을 가져와 사용할 수 있습니다.
(디자인 시스템을 만드는 경험과 관련된 내용은 별도의 포스팅으로..)

2-2. 탭별 모듈화 진행

2-1 과정이 어느 정도 완료되어 있으면 현재 프로젝트에서 두 개의 모듈이 생성되어 있는 상황일 것입니다. 그 이후에는 하단에 탭별로 모듈을 생성하여 해당 탭과 관련된 코드들은 새로 만든 모듈로 이동시킵니다. 이때도 Base 모듈을 만들 때와 동일하게 다른 모듈에 의존하는 코드가 있다면 분리하는 작업이 필요할 것으로 예상됩니다. (생각보다 서로 결합된 코드가 많기에 이 작업이 생각보다 어려울 것으로 예상됩니다.)

2-3. Tuist 도입

모든 모듈이 생성되면 Tuist를 도입하려고 합니다. 아직 프로젝트 파일 생성 도구를 사용하지는 않고 있지만 Base, FDS 모듈을 만들면서 수도 없이 겪고 있는 불편함 중에 하나가 협업하는데 모듈 사이에 발생하는 프로젝트 파일 충돌이기 때문에 모듈화를 진행할수록 프로젝트 파일 생성 도구를 도입하고자 하는 생각이 커질 것입니다.
추가로 Tuist에서는 SPM은 지원하지만 CocoaPod은 지원하지 않고 있기 때문에 2-1 ~ 2-2 과정을 진행하면서 옮길 수 있는 라이브러리들은 모두 SPM으로 옮기는 작업도 필요합니다.


모듈화해서 얻는 이득이 무엇일까? 🤔

1. 모듈 안에서는 지금보다 응집도 높은 코드를 만들 수 있고, 모듈 사이에는 의존성을 줄인 코드를 만들 수 있습니다.
2. 모듈별로 빌드 할 수 있으므로 볼륨이 큰 프로젝트를 효율적으로 관리할 수 있다.
3. 모듈별로 빌드 할 수 있으므로 빌드 타임을 줄일 수 있다. ▶️ 개발 효율이 올라간다!
4. 공통 라이브러리 코드의 재사용성이 증가한다. (Base, FDS)


위에 정리한 내용대로 설계와 계획을 세우고 현재 22년 8월 기준으로 2-1 과정을 진행하는 중에 있습니다.
과정을 진행하면서 겪고 있는 어려움, 불편함 들 과 해결한 방법을 계속 정리하여 업로드할 예정입니다.
처음으로 모듈화에 도전하는 것이기도 하고 스스로 리서치 해가면서 진행하는 상황이라 비효율적인 구조나 방법이 나올 수도 있다고 생각합니다. 언제든 더 좋은 방법이 있다면 그 방법으로 저를 후두려 까주세요!!