실무 프로젝트에서 Yarn classic/berry workspace
, Pnpm workspace
를 사용해봤고, 개인적으로 느낀 각각의 장단점을 가볍게 적어본다. 수치적으로 정확히 비교하는 글은 아니라는 거~
- 사실 구글 서치에서 내 블로그에 들어오는 검색어 1순위가
yarn berry monorepo
이기도 해서, 한번더 우려먹어보려는 거~
결론부터 말하면, 지금은 왠만하면 pnpm
을 사용해서 프로젝트를 구성하고 기존 yarn
으로 되어있던 모노레포 프로젝트도 pnpm
으로 이전하려고 하고 있다
의존성 설치 속도
체감상
pnpm
,yarn berry
둘다 비슷한 듯 하고, 둘다 빠르다yarn berry
는 순정 PnP 모드만 사용했을 때.yarn/cache
디렉토리에 의존성들을.zip
파일 형태로 저장한다.뇌피셜인데, 우선
zip
파일로 어느정도 압축이 되어있기 때문에 다운로드 용량 자체가 적어서 다운로드 시간 자체가 좀더 줄어들것 같고,npm
/yarn classic
처럼npm
레지스트리에 있는 패키지 내부 파일들을 하나하나 다운 받는게 아니라zip
파일 하나로 합쳐서 가져오기 때문에 http 요청-커넥션 프로세스도 줄어들기 때문에 좀더 빠르지 않을까 싶다zero-install
설정을 하게 되면, (거창해보이지만 사실 git에 .yarn 디렉토리 저장해버리는 거) CI 환경에서yarn install
을 안해도 되기 때문에(!) 짧게는 1분에서 많게는 몇분에 달하는 설치 시간을 아낄 수 있다.git
으로 의존성 변경을 확인할 수도 있기 때문에, 나도 모르게 의존성이 버전업 되서 빌드 깨지는 걸 미리 막을수 있고, 여러 사람이 참여하는 프로젝트에서 버전이 꼬이는 문제도 방지할 수 있다.
yarn classic
은,npm
=>yarn
으로 갈아타기 했을 때는 뭔가 좀 빠른듯 하고 CLI에 이모지도 있고 해서 뭔가 힙해보이는 느낌도 있어서 그런지 느리다는 느낌은 없었는데,pnpm
,yarn berry
를 쓰다가yarn classic
을 쓰면 아직도 설치하고 있네하는 생각이 든다
호환성
yarn classic
,pnpm
을 쓰면서는 호환성 문제가 발생한 적은 없다yarn berry
는 내가 마지막으로 썼던 작년 중반 정도까지 호환성 문제가 있어서, 설치에 실패하거나 vscode에서 패키지를 인식 못해서 ts 에러가 나는 경우가 많았다. 아직도 일부 라이브러리들은 호환성 문제가 있는 걸로 알고 있다.호환성 문제를 해결하려면 할 수도 있는데, 그 중 하나는 이전 블로그 (https://hashnode.com/post/ckyhgtckf08vw35s14ppr0fz3) 에서 썼던 거처럼 설정 파일
.yarnrc.yml
에서nodeLinker
를 설정해주는 방법이 있고,- 근데 이걸 하게 되면 의존성 설치하는게 두배가 된다. 이거는 아래 '디스크 사이즈'에서 알아보자
아니면
.yarnrc.yml
packageExtensions
를 활용해서 라이브러리 마다 하나하나 이건 이거고 저건 저거다 설정해주는 방법이 있다. 근데 이걸 해주는게 패키지 매니저의 역할인데, 이걸 못해서 사용자가 직접 해준다는게.. 근본적으로 틀려먹은거 아닌가 모르겠음
모노레포 툴인
turborepo
는yarn berry
와 호환이 안된다. 어차피 모노레포를 deep하게 쓰는게 아니라면yarn workspaces
그자체도 뭐 나쁘진 않은데,turborepo
의 캐싱 기능이 필요한 경우에는 좀 많이 아쉽다
디스크 사이즈
사실
node_modules
나.yarn/cache
,.pnpm-store
디렉토리 사이즈를 정확하게 비교분석 해본 적은 없다. 그런거 재고 있을 시간도 없고.. 다만 배포할 때 도커빌드하고서du
로 대충 어느정도 사이즈가 되는지 확인은 해보는 편인데, 세 패키지 매니저 모두 크게 차이는 없다다만 위 호환성 문제에서
yarn berry
를 사용할 때 패키지 인식 문제 때문에nodeLinker
를 설정해서node_modules
폴더를 사용하게 할 수가 있다. 그러면zip
파일로 설치한걸node_modules
에 한번 더 풀어서zip
파일로 인식이 안되면node_modules
에 있는걸 찾아서 사용하는 식이다.그러면 동일한 걸 하나는
.yarn/cache
안에서zip
파일로 갖고, 하나는node_modules
안에서 압축해제 한걸로 갖고 있게 되는 셈이된다. 위 스크린샷에서node_modules
폴더 사이즈가 무려 825메가가 나오는데,yarn berry nodeLinker
를 하게 되면 의존성만 1.6기가를 사용하게 되는 거다pnpm
도yarn berry
와 유사하게 PnP 모드를 사용하기 때문에node_modules
외에.pnpm-store
에 자체적으로 패키지들을 압축/변형한 걸 사용한다.pnpm install
을 할 때 우선.pnpm-store
에 압축된 파일들을 다운로드하고, 여기 있는 걸node_modules
에 풀어놓는 것 같다. 따라서npm
/yarn classic
보다는 디스크 용량을 좀더 차지할 수 있다
초기설정
npm은 Node.js를 설치하면, 왠만하면 자동으로 설치되는 거라 당연히 처음에 뭔가 해줄게 거의 없다
yarn classic
도npm i -g yarn
아니면corepack enable && corepack prepare yarn@latest --activate
정도 yarn 자체를 설치하는 거만 하면 바로 사용할 수 있다yarn berry
는yarn set version berry
로yarn berry
사용 설정을 해주고, 에디터에 맞는 sdk를 설치하고, 플러그인들을 설치해야 한다zero-install
같은 기능을 사용하려면.gitignore
에 어떤 디렉토리를 넣을 건지도 상황에 따라 고려해야 한다pnp
,zero-install
을 잘 쓰면 잘 쓸 수 있을 거고, 초기 설정들을boilerplate
로 만들어서 사용할 수도 있을 수 있겠지만, 아무튼 초기 설정하는데 손이 많이 간다. 귀찮다
pnpm
은 모노레포를 사용한다면pnpm-workspace.yml
파일을 추가해서 패키지 경로들을 지정해준다
CLI 편의성
pnpm은 npm/yarn classic을 써봤다면 거의 바로 사용할 수 있다.
의존성 설치를 할 때 npm 은
install
을 사용하고, yarn은 add를 사용하는데, pnpm은 둘다 쓸수 있다. 기분 내키는대로 하면 된다모노레포에서 특정 패키지에만 해당하는 명령어를 사용할 때는
pnpm --filter='..'
를 사용하면 되는데, 내부 패키지의 패키지명을 다 쓸 필요가 없어서 편하다. 예를 들어 내부 패키지명이@my-monorepo/app-a
라면pnpm --filter=app-a run 어쩌구
로 실행하면 된다
yarn은 classic/berry 둘다 workspaces에서 특정 패키지만 명령어를 사용할 때 해당 패키지명을 모두 써줘야 한다. 예를 들어 내부 패키지명이
@my-monorepo/app-a
라면yarn workspace "@my-monorepo/app-a" run 어쩌구
로 실행한다