🔥 모듈 별칭 재정의

257자
3분

여러분은 Swift 패키지를 개발하면서 종종 모듈 별칭(module alias) 값이 충돌하는 문제를 겪어보셨을 겁니다. 이런 상황에서는 다운스트림에서 모듈 별칭을 재정의(override)하여 문제를 해결할 수 있어요. 바로 moduleAliases 매개변수에 충돌하는 별칭 값을 키로 사용하고 고유한 값을 제공하는 항목을 추가하는 방식으로 말이죠.

이해를 돕기 위해, swift-drawswift-game 패키지를 다음과 같은 종속성과 모듈 별칭을 가지도록 수정해 볼게요.

swift-draw 패키지 매니페스트:

{
    name: "swift-draw",
    dependencies: [
        .package(url: https://.../a-utils.git),
        .package(url: https://.../b-utils.git),
    ],
    products: [
        .library(name: "Draw", targets: ["Draw"]),
    ],
    targets: [
               .target(name: "Draw",
                       dependencies: [
                            .product(name: "Utils",
                                     package: "a-utils",
                                     moduleAliases: ["Utils": "FooUtils"]),
                            .product(name: "Utils",
                                     package: "b-utils",
                                     moduleAliases: ["Utils": "BarUtils"]),
               ])
    ]
}
 
swift

위 코드에서는 a-utils 패키지의 Utils 모듈을 FooUtils로, b-utils 패키지의 Utils 모듈을 BarUtils로 별칭을 지정했어요.

이번에는 swift-game 패키지 매니페스트를 살펴보죠:

{
    name: "swift-game",
    dependencies: [
        .package(url: https://.../c-utils.git),
        .package(url: https://.../d-utils.git),
    ],
    products: [
        .library(name: "Game", targets: ["Game"]),
    ],
    targets: [
               .target(name: "Game",
                       dependencies: [
                            .product(name: "Utils",
                                     package: "c-utils",
                                     moduleAliases: ["Utils": "FooUtils"]),
                            .product(name: "Utils",
                                     package: "d-utils",
                                     moduleAliases: ["Utils": "BazUtils"]),
               ])
    ]
}
 
swift

여기서는 c-utils 패키지의 Utils 모듈을 FooUtils로, d-utils 패키지의 Utils 모듈을 BazUtils로 별칭을 지정했네요.

그런데 문제는 두 패키지 모두 FooUtils를 별칭으로 정의하고 있어서 다운스트림에서 충돌이 발생한다는 거예요. 이를 해결하기 위해 App 매니페스트에서 아래와 같이 모듈 별칭을 재정의할 수 있습니다.

    targets: [
        .executableTarget(
            name: "App",
            dependencies: [
                .product(name: "Draw",
                         package: "swift-draw",
                         moduleAliases: ["FooUtils": "DrawUtils"]),
                .product(name: "Game",
                         package: "swift-game",
                         moduleAliases: ["FooUtils": "GameUtils"]),
            ])
    ]
 
swift

위 코드에서는 a-utils 패키지의 Utils 모듈을 DrawUtils로, c-utils 패키지의 Utils 모듈을 GameUtils로 별칭을 재정의했어요. 각각의 재정의된 별칭은 해당 모듈에 의존하는 모든 타겟에 적용될 거예요.

이렇게 모듈 별칭을 재정의하면 충돌 문제를 깔끔하게 해결할 수 있습니다.