yarn workspace? lerna? 비유와 예시를 통해 이해해보기
대기업에 재직중인 yarn과 lerna가 있다. lerna는 대기업 팀장이고 yarn은 lerna 팀장 밑에서 일하는 직원이다. lerna는 여러가지 패키지들(packages)을 관리하는 관리자이다. yarn은 각 패키지 하나하나를 관리하는 사원이다.
lerna
는 관리자 역할을 오래 해왔기 때문에 각 패키지들을 배포하고 버전관리하는데 능숙하다.yarn
은 사원이기 때문에 각 패키지간의 의존성 관리를 잘한다.
lerna와 yarn을 같이 사용하는 이유가 위와 같다. 각 라이브러리가 잘하는일을 각자에게 맡긴다. lerna는 모노레포로 구성된 프로젝트 전체를 관리하고 yarn은 각 패키지들간의 의존성을 관리한다. 물론 lerna로도 yarn이 할수있는일들을 할수있지만, lerna로 패키지 의존성을 관리할때 이슈가 있다고 한다.
lerna bootstrap --hoist
위와 같이 lerna로도 모노레포의 각 패키지의 의존성을 연결하고 공통된 의존성들은 root에서 설치 및 관리하게 할 수 있다.
하지만 리액트로 만들어진 프로젝트에서 lerna bootstrap --hoist
로 패키지를 설치했을때 리액트 모듈을 중복해서 불러와 에러가 발생한다고 한다. 아직은 lerna로 패키지 의존성을 관리하는게 완벽하지 않은가보다.
그래서 많은 블로거들이 yarn과 lerna를 같이 사용해서 각자가 잘하는 부분을 맡게 하게끔 추천하고 있다.
다음과 같은 패키지 구조가 있다고 해보자.
package.json
packages/
sky
moon
sun
moon
과 sun
패키지는 sky
패키지를 사용한다.
의존성 추가를 하기 위해서 moon
과 sun
에서 다음과 같이 yarn 커맨드로 sky
패키지를 사용하자.
yarn workspace @monorepo/moon add @monorepo/sky@0.0.0 // moon패키지에 sky패키지를 추가
yarn workspace @monorepo/sun add @monorepo/sky@0.0.0 // sun패키지에 sky패키지를 추가
이런식으로 yarn workspace
를 사용해서 패키지의 의존성을 설치하고 관리한다. 그럼 sky
패키지가 moon
과 sun
패키지의 node_modules폴더 아래에 심볼릭링크로 들어가게 된다. 심볼릭링크라는건 그냥 이해하기 쉽게 바로가기 파일이라고 생각하면 된다.
원본 파일인 sky패키지가 수정되어도 node_modules폴더 아래에 있는 바로가기 sky패키지도 같이 수정되게 된다. 이런방식으로 각 npm패키지를 배포하지 않더라도 로컬 컴퓨터에서 서로 의존하고 있는 패키지들을 쉽게 수정하고 확인하고 테스트해볼수있다. 이제 moon패키지의 node_modules에 들어있는 sky 바로가기 패키지를 moon의 App.js
에서 import
해서 사용하면 된다.
의존성을 추가 할때 다음과 같이 lerna add
를 사용하면 어떻게 될까?
lerna add @monorepo/moon --scope=@monorepo/sky
lerna를 사용하면 버전을 명시 하지 않아도 되서 편리하지만, sky
패키지가 한번도 npm 저장소에 배포 된적이 없는 상태에서 sky
에 moon
패키지를 추가하려고 하면 sky
패키지를 찾을 수 없다는 에러가 나게 된다. 관련 이슈는 여기서 확인할수있다.
다시한번말하지만 패키지 의존성 관리는 lerna
보다 yarn
이 훨씬 에러없이 잘 하는 것 같다.