티스토리 뷰

도구 없이 모노레포를 구성하려고 하면 매우 귀찮다. 서로 의존하고 있는 패키지들을 npm link로 손수 연결해줘야 하기 떄문이다.(심볼릭 링크란?)  그래서 이런 작업들을 자동화 해주는 도구들을 소개한다.

yarn workspace? lerna? 

yarn에서는 workspace기능을 제공한다. workspace란 한국말로 '작업공간'이라는 뜻인데, 이 '작업공간'안에 들어있는 여러개의 패키지를 관리해주는 기능이라서 이런 이름이 지어진 것 같다.

 

lerna로도 패키지 관리를 할 수 있긴 하지만 yarn에서 workspace가 나오고 난 이후부터는 패키지 관리는 workspace로 하는 것이 보편화 되어 있다. 그래서 요즘은 보통 모노레포를 구성할때 yarn의 workspace와 lerna를 같이 사용하게 된다.

lerna?

yarn workspace는 최근에 업데이트 된 기능이다. 그전에는 모노레포를 구성하려고 할때 lerna만 사용해왔었다. lerna는 내부적으로 npm을 사용해서 패키지간 의존성 관리를 해왔다.

의존성이란?

A 패키지가 B 패키지를 사용하면 A는 B에 의존한다고 얘기한다. 왜냐면 A는 B의 변경사항에 영향을 받기 때문이다. '의존성 관리'란 하나의 패키지에서 사용하는 다른 패키지 목록들을 관리(추가, 수정, 삭제)하는것을 의미한다. npm에서는   package.json 파일로 의존성을 관리한다.

yarn workspace는 만능이 아니다.

모노레포는 각 패키지별로 독립적으로 배포가 가능해야 한다. 하지만 yarn workspace는 패키지 별로 버전관리하고 배포하는 기능을 갖고 있지 않다. 그래서 두개의 라이브러리를 같이 사용하는것이다. 그럼 그냥 yarn workspace를 사용하지 말고 lerna로 배포도하고 의존성관리도 하면 되지 않겠느냐고 반문할 수 있겠지만, 아무래도 lerna로 의존성 관리 하는것보다 yarn workspace로 관리하는게 더 이슈 없이 깔끔한가보다.

lerna

- 패키지 별 버전관리
- 패키지 별 배포
- npm scripts 실행 (패키지 전체 대상 혹은 특정 패키지만)

yarn workspace

- 패키지 간 의존성 설치 및 관리(symlink)

 

lerna와 npm

lerna bootstrap --hoist

위 명령어를 실행하면 각 패키지의 루트에서 npm install을 실행한다. --hoist옵션을 주지 않으면 각 패키지 루트에 모듈을 설치하지만 옵션을 주면 레포지토리 루트에서만 라이브러리가 설치된다. 

/node_modules/*

hoist 옵션을 줘서 설치하는 경우 위와 같이 repository root의 node_modules에 모든 라이브러리들이 집합된다.

lerna와 yarn

lerna는 기본적으로 패키지 관리 도구로 npm을 사용한다. npm대신 yarn을 사용하고 싶으면 lerna.json 파일에 npmClient를 yarn으로 설정해줘야한다. 디폴트인 npm을 사용하는것과 큰차이는 없지만 yarn의 workspaces 기능을 사용하고 싶다면 반드시 설정해줘야 한다. 만약에 패키지별 배포는 할 필요가 없고 의존성 관리만 한다면 굳이 lerna를 사용하지 않고 yarn의 workspace만 사용해도 된다.

 

lerna와 yarn workspace를 같이 쓰는건 lerna가 하고 있던 일부 기능을 yarn에게 양도한것이다. 왜냐면? 패키지간 의존성 관리는 yarn으로 하는게 더 낫기 떄문이다.

 

yarn의 workspace기능을 사용하려면 private:true, workspaces: []는 반드시 설정해줘야 한다.

만약에 lerna없이 yarn workspace만 사용할거라면 위 설정만 있어도 충분하다. yarn workspace 기능을 사용하는 상태에서 터미널에 yarn만 입력해주면, 각 패키지의 모듈을 모아서 루트에 딱 한번만 설치하고, 서로 의존하는 로컬 패키지들은 심볼릭 링크를 통해 연결된다. yarn workspace의 yarn install은 lerna bootstrap --hoist 명령과 똑같이 동작한다. 하지만 패키지별 버전관리와 배포, npm scripts 실행등은 아직 yarn에서 제공하지 못하기 때문에 이 부분은 lerna가 해줘야한다.

 

lerna와 yarn workspace를 같이 사용하는 경우

lerna와 workspace를 같이 사용하는 경우 lerna.json에 useWorkspaces: true로 설정해줘야한다. 이렇게 되면 패키지 관리는 workspace가 하게 된다. 패키지 설치시 lerna bootstrap대신 yarn만 입력해주면된다.

 

yarn workspace의 hoist

yarn workspace는 의존성 관리를 루트에서만 하게 된다. 이 특징을 'hoist'라고 하는데 hoist를 지원하지 않는 라이브러리의 경우에는 이 디폴트 옵션을 꺼줘야한다. package.json에 nohoist 옵션을 주면 된다.

"workspaces": {
    "packages": ["packages/*"],
    "nohoist": [
      "**/react-native"
    ]
  }

이렇게 하면 react-native는 레포지토리 루트에 설치되지 않고 패키지 루트에 설치된다.

 

예시

다음과 같은 패키지 구조가 있다고 해보자.

 

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에서는 수정된 버전의 sky를 가져다 쓰게 된다. 서로 심볼릭 링크로 연결되어 있기 때문이다.

 

이런방식으로 각 npm패키지를 배포하지 않더라도 로컬 컴퓨터에서 서로 의존하고 있는 패키지들을 쉽게 수정하고 확인하고 테스트해볼수있다. 이렇게 의존성을 설치해주고 나서는 그냥 평소에 import하던것처럼 하면 된다. 여기서 주의할것은 마지막에 @0.0.0과 같이 버전 정보를 정확히 적어줘야 설치가 제대로 된다는것이다. 버전을 명시하지 않으면 yarn은 npm 레포지토리에서 패키지를 찾게 된다. 로컬은 찾아보지도 않고 에러를 내버린다. (이부분이 조금 귀찮다.)

 

의존성을 추가 할때 다음과 같이 lerna add를 사용하면 어떻게 될까?

lerna add @monorepo/sky --scope=@monorepo/moon
lerna add @monorepo/sun --scope=@monorepo/moon

lerna로 의존성 관리를 할때는 한번에 하나의 패키지씩만 설치할 수 있다. 공식문서의 lerna add 사용법을 알아보자.

# module-1 패키지를 packages의 prefix- 라는 prefix를 가진 폴더에 모두 추가한다.
lerna add module-1 packages/prefix-*

# module-1 패키지를 module-2 패키지에 설치함.
lerna add module-1 --scope=module-2
lerna add module-1 --scope=module-2 --dev
lerna add module-1 --scope=module-2 --peer

# module-1 패키지를 본인을 제외한 모든 패키지에 설치함.
lerna add module-1

# babel-core를 본인 포함 모든 패키지에 설치함. (npm repository에서)
lerna add babel-core

하지만 lerna로 패키지를 관리하면 이슈가 생길 가능성이 있기 떄문에 yarn workspace로 패키지를 설치하도록 하자.

 

 

출처

https://doppelmutzi.github.io/monorepo-lerna-yarn-workspaces/

 

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함