🔥 Swift 패키지 매니저에서 모듈 별칭 사용하기
Swift 패키지 매니저(이하 SPM)에서는 서로 다른 패키지에서 동일한 이름의 모듈을 사용할 때 충돌이 발생할 수 있습니다. 이러한 모듈 이름 충돌을 해결하기 위해 SPM은 모듈 별칭(Module Aliasing) 기능을 제공합니다. 이 글에서는 모듈 별칭(Module Aliasing)을 사용하는 방법과 예제를 통해 자세히 살펴보겠습니다.
사용 시나리오
모듈 별칭(Module Aliasing)을 사용하는 상황을 다음과 같은 시나리오를 통해 알아봅시다.
예제 1
App
프로젝트는 swift-draw
패키지에서 Utils
모듈을 가져옵니다. 그런데 App
은 또 다른 패키지인 swift-game
에 의존하고 싶고, 해당 패키지에서도 Utils
모듈을 제공합니다.
App |— Module Utils (from package 'swift-draw') |— Module Utils (from package 'swift-game')
text
swift-game
패키지의 매니페스트 파일은 다음과 같습니다.
{ name: "swift-game", products: [ .library(name: "Utils", targets: ["Utils"]), ], targets: [ .target(name: "Utils", dependencies: []) ] }
swift
swift-draw
패키지의 매니페스트 파일은 다음과 같습니다.
{ name: "swift-draw", products: [ .library(name: "Utils", targets: ["Utils"]), ], targets: [ .target(name: "Utils", dependencies: []) ] }
swift
swift-draw
와 swift-game
패키지 모두 Utils
라는 동일한 이름의 모듈을 제공하므로 충돌이 발생합니다. 이를 해결하기 위해 moduleAliases
매개변수를 사용하여 모듈 이름을 구분할 수 있습니다.
App
프로젝트의 매니페스트 파일에서 다음과 같이 moduleAliases
를 설정합니다.
targets: [ .executableTarget( name: "App", dependencies: [ .product(name: "Utils", package: "swift-draw"), .product(name: "Utils", package: "swift-game", moduleAliases: ["Utils": "GameUtils"]), ]) ]
swift
moduleAliases
매개변수의 값은 딕셔너리 형태로, 충돌하는 원래 모듈 이름을 키로, 사용자 정의 고유한 새 이름을 값으로 지정합니다. 여기서는 swift-game
패키지의 Utils
모듈을 GameUtils
로 이름을 변경했습니다. 이렇게 하면 swift-game
패키지의 바이너리 이름은 GameUtils.swiftmodule
이 됩니다. swift-game
패키지에서는 소스 코드나 매니페스트 파일을 변경할 필요가 없습니다.
별칭이 지정된 모듈을 사용하려면 App
프로젝트에서 새로운 이름인 import GameUtils
를 참조해야 합니다. 기존의 import Utils
문은 예상대로 swift-draw
패키지의 Utils
모듈을 계속 참조합니다.
의존성 제품 이름이 중복되더라도, 즉 Utils
라는 동일한 이름을 가지더라도 모듈 별칭(Module Aliasing)을 사용하면 허용됩니다. 단, 동일한 제품 이름의 파일이 여러 개 생성되지 않아야 합니다. 이는 모든 제품이 자동 라이브러리 유형이거나, 최대 하나만 정적 라이브러리, 동적 라이브러리, 실행 파일 또는 제품 이름으로 파일이나 디렉토리를 생성하는 다른 유형이어야 함을 의미합니다.
예제 2
App
프로젝트는 swift-draw
패키지에서 Utils
모듈을 가져옵니다. 그리고 swift-game
패키지에 의존하고 해당 패키지에서 제공하는 Game
모듈을 가져오고 싶습니다. Game
모듈은 동일한 패키지 내의 Utils
모듈을 가져옵니다.
App |— Module Utils (from package 'swift-draw') |— Module Game (from package 'swift-game') |— Module Utils (from package 'swift-game')
text
swift-game
패키지의 매니페스트 파일은 다음과 같습니다.
{ name: "swift-game", products: [ .library(name: "Game", targets: ["Game"]), ], targets: [ .target(name: "Game", dependencies: ["Utils"]) .target(name: "Utils", dependencies: []) ] }
swift
예제 1과 유사하게 두 패키지 모두 Utils
라는 동일한 이름의 모듈을 포함하므로 충돌이 발생합니다. App
프로젝트에서 swift-game
패키지의 Utils
모듈을 직접 가져오지 않더라도 충돌하는 모듈의 이름을 구분해야 합니다.
다음과 같이 moduleAliases
를 사용할 수 있습니다.
App
프로젝트의 매니페스트 파일:
targets: [ .executableTarget( name: "App", dependencies: [ .product(name: "Utils", package: "swift-draw"), .product(name: "Game", package: "swift-game", moduleAliases: ["Utils": "GameUtils"]), ]) ]
swift
swift-game
패키지의 Utils
모듈은 GameUtils
로 이름이 변경되고, Game
모듈의 소스 파일에서 Utils
에 대한 모든 참조는 GameUtils
로 컴파일됩니다. 예제 1과 마찬가지로 swift-game
패키지에서 소스 코드나 매니페스트 파일을 변경할 필요가 없습니다.
더 많은 별칭을 정의해야 하는 경우 쉼표로 구분하여 추가할 수 있습니다.
moduleAliases: ["Utils": "GameUtils", "Logging": "GameLogging"]),
swift
이렇게 모듈 별칭(Module Aliasing)을 사용하면 서로 다른 패키지에서 동일한 이름의 모듈을 사용할 때 발생하는 충돌을 해결할 수 있습니다. 모듈 이름을 별칭으로 지정하여 구분함으로써 원활하게 패키지를 관리할 수 있게 됩니다.
모듈 별칭(Module Aliasing)은 SPM의 강력한 기능 중 하나로, 패키지 간의 모듈 이름 충돌 문제를 우아하게 해결해 줍니다. 이 기능을 활용하여 프로젝트에서 다양한 패키지를 원활하게 통합하고 관리할 수 있습니다. 코드의 가독성과 유지 보수성을 높이는 데에도 도움이 될 것입니다.