Tuist Scaffold로 모듈 생성 자동화 하기 + 외부 Dependencies 추가하기

이번에는 이전에 Tuist를 활용해 모듈화를 구성했다면 추후 모듈화를 자동화하여 편리하게 사용할 수 있는 환경 세팅을 해주기 위해 Scaffold로 자동화를 해주고 그 이후 외부 Dependency를 추가해보려고 한다.

 

먼저 Scaffold를 적용시켜보자!

 

Tuist를 통해 모듈화하는 이전 세팅이 완료된 상황에서 진행해 보려고 한다.

우선 Manifests/Tuist/Templates/Feature 디렉토리까지 만들어 둔 다음 Feature 내부에 Sources 그룹과 Feature.swift 파일을 만든다!

mkdir -p Tuist/Templates/Feature/Sources

터미널을 활용해 만들어주면 한번에 완성이 된다.

그 다음 Feature.swift 파일 내 템플릿 파일을 구성해 주어야 한다.

import ProjectDescription

let nameAttribute: Template.Attribute = .required("name")

let template = Template(
    description: "Feature Module Template",
    attributes: [nameAttribute],
    items: [
        .file(
            path: "Projects/\\(nameAttribute)/Project.swift",
            templatePath: "Project.stencil"
        ),
        .directory(
            path: "Projects/\\(nameAttribute)",
            sourcePath: "Resources"
        ),
        .directory(
            path: "Projects/\\(nameAttribute)",
            sourcePath: "Sources"
        ),
        .file(
            path: "Projects/\\(nameAttribute)/Sources/Example.swift",
            templatePath: "Sources/Example.swift.stencil"
        )
    ]
)

여기서 주의해야할 점은 Resource 를 추가해주기 위해 file 을 디렉토리 보다 위에 배치했더니 디렉토리가 만들어지기 전에 file이 읽어져 오류가 발생헀다는 점이다.

 

디렉토리가 먼저 읽어져서 해당 파일이 들어갈 디렉토리가 만들어진 뒤 파일이 만들어질 수 있도록 순서를 신경써서 넣어주어야 한다.

 

그 다음 Project.stencil 파일을 만들어 자동으로 생성될 Project 파일의 템플릿을 넣어준다.

import ProjectDescription

let project = Project(
    name: "{{ name }}",
    targets: [
        .target(
            name: "{{ name }}",
            destinations: .iOS,
            product: .framework,
            bundleId: "com.Tuist-Test.{{ name }}",
            infoPlist: .default,
            sources: ["Sources/**"],
            resources: [],
            dependencies: []
        )
    ]
)

나는 이전 모듈로 만들어진 내용과 동일하게 사용하는 것으로 오류를 최소화 하는 방향으로 구성했다. 여기서 또 주의해야할 점은 bundleId를 다른 모듈과 다르게 설정하게 된다면 정상적으로 모듈 생성이 안된다는 점! 번들아이디 동일하게 구성할 수 있도록 신경써서 넣어준다.

 

그 다음 Sources 디렉토리 내 Example.swift 파일이 완성되도록 만들어서 tuist generate를 했을때 폴더 구조가 명확하게 생성되도록 할 필요가 있다!

import Foundation

public final class {{ name }} {
    public init() {}

    public func start() {
        print("{{ name }} 모듈 시작!")
    }
}

이 스텐실 파일은 Sources 디렉토리 내부에 생성될 예정이기 떄문에 메니페스트 내 구조에서도 Sources 내부로 위치하도록 구성해야한다.

 

이렇게 구현 했다면 예를 들어 Login 모듈을 만든다고 가정했을때 워크스페이스에 해당 모듈을 추가해준다.

let workspace = Workspace(
    name: "Tuist_Test",
    projects: [
        "Projects/App",
        "Projects/Core",
        "Projects/Domain",
        "Projects/Data",
        "Projects/Presentation",
        "Projects/Login"
    ]
)

이제 설정이 모두 완료되었다면 프로젝트 루트 파일에서 아래와 같은 명령어를 실행 시켜주면!

tuist scaffold Feature --name Login

사진과 같이 Login 모듈이 자동으로 생성되어 있고 Package에서 지정한 내용대로 디렉토리 구조가 만들어져 손 쉽게 모듈 구성이 가능해진다.

 

여기까지 scaffold 사용법에 대해서 알아봤다!


다음은 외부 Dependency를 추가해보자

 

버전이 업데이트 되면서 바뀐 내용이 있는 것 같다. 공식 문서를 확인해보니 이와 같이 프로젝트 루트나 하위에 Package.swift를 만들어야 한다고 되어있는데 다른 자료들은 Dependencies를 만들어야 한다고 하는 것 보니 변경 점이 있는 것 같다.

아무튼 이 Tuist/Package는 초반 tuist를 시작했을때 자동으로 만들어져있었다.

사진과 같이 Scaffold를 만들어주는 Feature 부분에 이미 Package가 만들어져 있었고 해당 부분에 외부 의존성을 추가하면 된다!

// swift-tools-version: 6.0
import PackageDescription

#if TUIST
    import struct ProjectDescription.PackageSettings

    let packageSettings = PackageSettings(
        productTypes: [
            "Alamofire": .framework, // default is .staticFramework
        ]
    )
#endif

let package = Package(
    name: "tuist",
    dependencies: [
        .package(url: "<https://github.com/Alamofire/Alamofire>", from: "5.0.0"),
    ]
)

아래와 같이 알라모 파이어를 추가해줬다고 가정했을때 이렇게 Package 파일에 해당 내용을 넣어주고

tuist install

로 생성을 해주면! 성공적으로 완성되었다고 한다!

이 내용을 Login 모듈에 디펜던시로 추가하게 되면

import ProjectDescription

let project = Project(
    name: "Login",
    targets: [
        .target(
            name: "Login",
            destinations: .iOS,
            product: .framework,
            bundleId: "com.Tuist-Test.Login",
            infoPlist: .default,
            sources: ["Sources/**"],
            resources: [],
            dependencies: [
                .external(name: "Alamofire"),
            ]
        )
    ]
)

external를 통해 간단하게 적용할 수 있고 이를 바탕으로 generate를 실행하면 사진과 같이 Dependencies가 생성되어 하단에 추가한 알라모파이어가 있는 것을 확인할 수 있다!

로그인 모듈에 해당 외부 의존성이 추가되어있는게 확인된다면 끝!!!

다음에는 추가적으로 Helper를 사용해서 더욱 시스템적으로 tuist를 편리하게 사용할 수 있는 환경을 만들어줄 수 있는 플러그인도 다뤄볼 예정이다!

 

오늘은 여기까지!!