Yarn workspace로 모노레포 관리시 발생할 수 있는 문제
모노레포를 더 효율적으로 관리할 수 있는 방법을 알아보던 중, yarn에서 제공하는 workspaces라는 도구를 발견하였고, 도입을 위해 몇 가지 시나리오의 패키지 버전 테스트를 진행한 내용을 지난 번 포스팅에 작성하였습니다.
이번 포스팅에서는 지난 번 포스팅에 이어 yarn workspaces의 특징인 호이스팅으로 인해 언젠가 누군가는 겪을 수 있고, 문제로 이어질 수도 있는 상황을 공유해보겠습니다.
본 포스팅에서는 packages 하위에 package-a, package-b 라는 프로젝트가 존재하고, 두 프로젝트가 공통으로 사용하는 서버를 shared-utils로 두는 구조를 예시로 살펴보았습니다.
packages
┣― package-a
┣― shared-utils
┗― package-b
package-a와 package-b가 공통으로 사용하는 모듈인 shared-utils 내부에는 데이터베이스 model을 정의하고, 데이터를 읽고 쓰는 로직들이 위치합니다.
그래서 package-a와 package-b 두 프로젝트에서는 products와 users라는 공통의 DB를 사용하는 데이터를 읽고 쓰는 대부분의 로직이 shared-utils 모듈의 DB 연결 함수를 불러오는 위 이미지와 같은 형태로 이루어져 있습니다.
package-a, package-b, shared-utils 세 프로젝트에서는 모두 sequelize 라이브러리를 사용하고 있습니다.
그런데 모노레포인 경우이지만 일반적이지 않은 아래와 같은 전제가 있다고 가정을 해봅니다.
프로젝트가 거대해지면서 해당 프로젝트에서 팀이 A팀과 B팀으로 분리가 되고,
- package-a는 A팀에서 사용
- package-b는 B팀에서 사용
하게 된다는 전제입니다.
이런 경우에 yarn-workspace를 도입하려면, 아래와 같은 상황에서 문제가 발생할 수 있을 것 같았습니다.
- package-a를 사용하는 A팀에서 sequelize 라이브러리를 ^6.8.0에서 ^6.33.0 으로 업그레이드 해야 하는 상황
- package-b를 사용하는 B팀에서는 ^6.8.0를 유지해야 하는 상황
- package-a 프로젝트와 package-b 프로젝트 모두 dockerfile에서 shared-utils를 COPY해와서 빌드한 후에 배포해서 사용하는 상황
package-a 프로젝트 내부의 package.json 파일에서 sequelize 라이브러리의 버전을 ^6.33.0 로 명시해도 아래 lodash의 예시와 같이 6.8.0을 사용하게 될 가능성이 있고, 이 모든 상황이 매번 헷갈릴 수 있음.
lodash 예시
package-a / package-b 가 동일한 패키지 버전을 사용하다가 package-a만 버전이 변경되는 경우 - 마이너 버전 변경
캐럿(^) 사용 시
- 최상단 package/node_modules에 패키지가 설치되고, yarn.lock 파일이 변경됨 (마이너 버전과 패치 버전이 달라도 메이저 버전이 같다면 최상단에 하나만 설치됨)
- yarn.lock 파일이 변경됨
변경 전
lodash@^3.1.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==
변경 후
lodash@^3.1.0, lodash@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==
캐럿 (^) 사용하지 않을 시
- package-a / package-b / package-c 모두 ^3.1.0 버전의 lodash를 사용하여 최상단 server/node_modules에만 lodash ^3.1.0 버전이 설치되어 있을 때 → pacakge-a의 lodash 버전을 ^3.10.1로 변경하고, package-b의 버전에서 캐럿(^)을 제거한 3.1.0으로 설정 시 → package-b 경로에만 3.1.0 버전의 패키지가 설치되고, server/node_modules 최상단에 3.10.1 설치됨
- server/yarn.lock 파일
변경 전
lodash@^3.1.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==
변경 후
lodash@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.1.0.tgz#d41b8b33530cb3be088853208ad30092d2c27961"
integrity sha512-kH7H/6T8ut2DMWAHIKJWZoDzYdvy+echL6u2VZbhYYkEjr6Zp15Yjt9pPvIPQwAT/5QaQYdaVPwCcLMP9qeu0w==
lodash@3.10.1, lodash@^3.1.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R
라이브러리의 버전을 변경하는 것은 어떻게 보면 간단한 일일 수 있지만, 프로젝트가 거대해질수록 알 수 없는 부분에 영향을 미칠 수 있는 중요한 요인이 될 수 있으므로, 이러한 특수 상황에서는 yarn workspaces와 같은 도구를 사용한다면 때에 따라 문제가 발생할 수도 있으므로 주의해서 사용하면 좋을 것 같습니다.