LODY/노트
← Notes

SyncSwift 2022: Tuist로 모듈을 나누는 방법 (이명환님 세션 정리)

·
#SyncSwift#Tuist#모듈화#SwiftPM#빌드

SyncSwift 2022에서 이명환님의 Tuist 세션을 정리한다. 주제는 하나였다. 어떻게 모듈을 분리할 것인가. 당시 Sendy 앱도 규모가 커지면서 화면·기능을 모듈로 쪼개는 고민을 하던 시기라 관심 있게 들었다.

모듈 분리가 어려운 이유

프로젝트를 모듈로 나누는 게 말처럼 쉽지 않은 이유가 두 갈래로 정리됐다.

첫째, 프로젝트와 프레임워크를 손으로 만들고 관리해야 한다. 애플리케이션이 동적 프레임워크를 Embed 하지 않으면 런타임 에러가 나고, 반대로 정적 프레임워크나 라이브러리를 쓰면 코드가 중복 복사되는 문제가 생긴다. 모듈이 늘어날수록 이 설정을 사람이 일일이 챙기는 건 위험하다.

둘째, SwiftPM의 제약이다. Configuration이 Debug와 Release만 제공되어 Develop, Test, Staging, Prod 같은 여러 환경을 나누기 어렵고, 당시에는 참고자료도 부족했다.

Tuist가 푸는 방식

Tuist는 이 문제를 Swift로 프로젝트 정의(Manifest)를 작성하는 방식으로 접근한다. 프로젝트 구성을 코드로 쓰니 템플릿화해서 재사용하고 관리하기 쉽고, 동적 프레임워크와 정적 프레임워크를 구분해 쓸 수 있으며, 조건에 따라 프로젝트와 워크스페이스 생성을 제어할 수 있다. 환경 변수로 분기 처리(특정 환경 변수가 없을 때, 값이 Y일 때 등)를 하거나 특정 프로젝트를 기준으로 워크스페이스를 구성하는 것도 가능하다. 정리하면 Tuist는 Manifest 언어, 템플릿, 의존성 그래프 생성, 환경 변수, 조건부 동적 생성을 제공한다.

세션에서는 Tuist의 프로젝트 생성 방식을 슬라이드로 풀어 설명했다.

Tuist의 프로젝트 생성 방식 전체 구조

Project Description(Manifests)이 App, DesignSystem, Network 같은 모듈별 Manifest와 Dependencies, Workspace를 정의한다. 실제 Xcode에서는 App이 프로젝트, DesignSystem과 Network가 모듈로 잡힌다.

프로젝트와 모듈 구성

각 App Manifest는 Project.swift와 Resources, Sources로 구성된다.

App Manifest의 구성 요소

Project.swift는 import ProjectDescription으로 시작해 name, target, product, bundleId, sources, resources, headers, dependencies를 선언한다. Xcode 프로젝트 파일을 GUI로 만지는 대신 이 코드가 그 역할을 대신한다.

Project.swift 예시

의존성은 Carthage나 SPM으로 관리한다.

의존성 관리

전체 흐름은 tuist edit로 Manifest를 수정하고, tuist generate로 Xcworkspace를 만들고, tuist fetch로 의존성을 가져오는 세 단계로 돌아간다.

tuist edit / generate / fetch 흐름

정리하며

핵심은 Xcode 프로젝트 설정을 사람이 GUI로 관리하던 것을 코드로 옮긴다는 발상이다. 모듈이 많아질수록 프로젝트 파일 충돌과 수동 설정이 병목이 되는데, Tuist는 그 설정을 Swift 코드와 템플릿으로 고정해 재현 가능하게 만든다. 당시에는 바로 도입하진 못했지만, 이후 모듈화와 빌드 자동화를 고민할 때 프로젝트 생성 자체를 코드로 다룬다는 관점이 계속 참고가 됐다.