THE STEADY COMPANY
모듈 목적에 맞게 나누기 cover image

모듈 목적에 맞게 나누기

단일 패키지 실험과 멀티 패키지로의 회귀

2025-01-14 21:00

·
  • iOS
  • Modularization
  • SwiftPM
  • Architecture

들어가며

최근 isowords 프로젝트를 보면서
기존의 멀티 패키지 구조를 단일 패키지 기반으로 병합해보기로 했어요.

선택의 이유는 단순했어요.

  • 패키지가 많아질수록 관리 포인트가 늘어나요
  • 단일 패키지로 합치면 구조 파악과 관리가 더 쉬워지지 않을까?
  • 디렉토리 구조를 활용해, 다른 언어처럼 파일 시스템 기반 import를 유기적으로 활용할 수 있지 않을까?

결론부터 말하면, 실패했어요.


단일 패키지의 함정: 복잡도의 폭발

막상 단일 패키지로 합쳐보니
관리 포인트는 줄어들었지만, 복잡도는 기하급수적으로 증가했어요.

  • 의존성 경계가 흐려져요
  • 모듈 간 책임이 코드 레벨에서 강제되지 않아요
  • "여기까지가 이 영역"이라는 감각이 점점 사라져요

특히 기대했던\

"디렉토리 기반으로 유기적인 import가 가능하지 않을까?"

라는 가설은 현실과 맞지 않았어요.

SwiftPM은 결국 Target 단위의 의존성 관리가 핵심이고,
디렉토리는 그저 정리 수단일 뿐이었어요.


다시 멀티 패키지로

그래서 다시 멀티 패키지 구조로 돌아가기로 했어요.
다만, 이전과는 기준이 조금 달라졌어요.

기준 1: Feature는 단일 패키지

Feature 단위는 여전히 하나의 패키지로 유지하고 있어요.
Feature 내부에서의 응집도가 가장 중요하다고 판단했기 때문이에요.

기준 2: 외부 의존성이 강한 영역부터 분리

특히 다음과 같은 패키지들은 거의 코드 변경이 없고,
플랫폼 성격이 강했어요.

  • 광고 패키지
  • 플랫폼 의존 패키지
  • 인증(Auth) 관련 패키지

이런 패키지들은

  • 외부 라이브러리 의존성이 강하고
  • 다른 Feature들과의 결합도가 낮으며
  • 변경 가능성도 낮아요

그래서 패키지로 분리해 격리시키는 것이 더 합리적이었어요.


AppFeature와 Composition Root의 고민

또 하나 고민이 있었던 지점은
AppFeature라는 루트 역할 + Composition Root 역할을 하는 모듈이었어요.

현재 서비스는

  • Dev
  • Stage
  • Production

멀티 타겟 환경으로 운영 중이에요.

문제는 이 환경 차이를
Interface / Live 구조로 나누기 애매한 영역이 점점 늘어난다는 점이었어요.


App 전용 패키지로의 분리 아이디어

그래서 든 생각은 이거였어요.

App 자체를 하나의 패키지로 보고
환경별 모듈을 그 안에서 명시적으로 나누면 어떨까?

구조는 대략 이런 느낌이에요.

.target(
  name: "AppFeature",
  dependencies: [
    /* App 공통 Feature */
  ]
),
.target(
  name: "AppDev",
  dependencies: [
    "AppFeature",
    /* Dev 전용 모듈 */
  ]
),
// AppStage, AppProduction...

이렇게 하면 얻을 수 있는 장점이 꽤 명확해요.

  • 환경별 의존성이 코드 레벨에서 분리돼요
  • Dev 전용 도구(Playbook, Debug UI 등)는 AppDev에만 존재해요
  • Stage / Production은 더 깔끔한 의존성 그래프를 유지할 수 있어요
  • Composition Root의 책임이 명확해져요

마치며

이번 구조 변경을 하면서 다시 느낀 점은 이거예요.

모듈은 "나누는 기술"이 아니라
의도를 강제하는 장치예요.

  • 거의 변하지 않는 영역은 과감히 격리하고
  • 자주 변하는 영역은 응집도를 높이고
  • 환경 차이는 구조로 드러나게 만들어요

단일 패키지가 항상 정답은 아니고,
멀티 패키지도 무조건 복잡한 건 아니에요.

중요한 건, 모듈이 왜 존재하는지 스스로 설명할 수 있느냐인 것 같아요.

이 구조도 언젠가는 다시 바뀔 수 있겠지만,
적어도 지금 기준에서는 꽤 합리적인 선택이라고 느끼고 있어요.