최근 기업들의 공고를 보면 기술 스택에서 yarn berry를 심심찮게 볼 수 있었다. 보통 yarn은 npm과 함께 패키지 관리 도구로 양대산맥을 이루고 있기 때문에 알고있지만, yarn berry에 대해서는 아직 알지 못하기 때문에 한번 이번 기회에 어떤 것인지 정리하고 어떤 부분 때문에 요즘 잘 쓰이고 있는지 간결하게 정리해보고자 한다.
1. yarn berry가 등장한 배경#
yarn berry라고 불리지만 사실은 yarn v2라고 할 수 있다. 일단 yarn berry에 대해서 알기 위해서는 왜 기존에 npm과 yarn(v1)이 있는데 yarn berry가 등장했는지를 살펴봐야 한다. 기존 npm의 문제점을 먼저 살펴보면 아래와 같다.
-
lock 파일이 없어 생기는 패키지의 버저닝/의존성 이슈가 존재
-
보안 이슈가 존재
-
패키지가 늘어날수록 성능 저하 발생
이러한 문제점들이 있었기 때문에, 새로운 패키지 매니저인 yarn이 등장하였다. yarn은 npm의 위와 같은 문제점들을 보완하기 위해 아래와 같은 특징들을 가지고 있었다.
-
yarn.lock 파일 자동 생성, 체크썸을 통해 어떤 환경이든 동일한 패키지 설치 지원
-
의존성 트리 이슈는 lock파일과 알고리즘을 통해 개선
-
패키지 병렬 설치를 통한 성능 개선
-
캐시 디렉터리(cache directory)를 통한 오프라인 미러링과 left-pad 이슈 방지
이렇게 yarn은 여러가지를 보완하여 나왔지만 여전히 yarn과 npm의 공통적인 문제점들이 남아있었다.
1. node_modules의 거대함

node_modules의 depth와 용량은 간단한 패키지 몇개의 설치만으로도 매우 커지게된다. 만약 next.js같은 프레임워크나 라이브러리를 사용하게된다면, node_modules는 기가 단위의 용량을 사용할 수도 있게 무거워진다. 거기에 depth는 점점 깊어져 삭제, 수정, 실행등의 속도에 영향을 끼치게 된다.
NPM은 패키지를 찾기 위해 상위 디렉토리의 node_modules 폴더를 탐색하기 때문에 패키지를 찾지 못할 수록 I/O속도는 느려진다. 패키지를 찾지 못하면 상위 디렉터리의 node_modules를 계속 검사하는 것이다.
2. 유령 의존성(Phantom Dependency)

hoisted 되면서 설치한적이 없는 패키지를 사용할 수 있게 되는 것이 유령 의존성이다. 이런 이슈는 package.json을 통해 설치 되지 않은 패키지를 사용할 수 도 있고, 삭제할 때도 사용하던 패키지를 사용할 수 없게 되기도 한다. 개발 과정에서 이러한 이슈로 많은 시간이 낭비되기도 한다. 뿐만 아니라 패키지를 삭제할 때 의존성을 정확히 파악하기 어려워서 삭제를 못하거나 버전 업그레이드가 어려워지는 상황도 많이 일어난다.
2. yarn berry는?#
위와 같은 공통적인 문제를 가지고 있던 상황에서 2018년 yarn berry가 등장했다. yarn berry(v2)에서는 pnp(plug’n’play)라는 개념을 도입해서 여러 이슈들을 해결해주었다. yarn v2에서는 비효율적인 node_modules 대신 .pnp.cjs라는 파일을 생성한다. 그리고 해당 파일은 아래와 같은 포맷을 가진다. 패키지 이름과 버전, 패키지의 실제 위치를 담은 맵과, 패키지 이름, 패키지 버전 그리고 패키지의 종속성을 담은 맵은 저장한다.
["@ant-design/react-slick", [ //패키지 이름
["npm:0.28.3", { //패키지 버전
//패키지 경로
"packageLocation": "./.yarn/cache/@ant-design-react-slick-npm-0.28.3-ece1f2feb7-887cb395bd.zip/node_modules/@ant-design/react-slick/",
"packageDependencies": [ //패키지 종속성
["@ant-design/react-slick", "npm:0.28.3"],
["@babel/runtime", "npm:7.14.6"],
["classnames", "npm:2.3.1"],
["json2mq", "npm:0.2.0"],
["lodash", "npm:4.17.21"],
["resize-observer-polyfill", "npm:1.5.1"]
],
"linkType": "HARD",
}]
]],이렇게 .pnp.cjs 파일을 사용하는 것은 여러가지 이점을 가지고 있다.
-
.pnp.cjs파일 하나만 생성하여 설치가 빨라진다. -
disk I/O 사용이 줄어들어 안정적인 설치가 가능하다.
-
종속성 트리의 최적화 및 예측가능한 패키지를 인스턴스화한다.
-
repository에
.pnp.cjs를 커밋할 수 있고, 다른 곳에서도yarn install을 할 필요가 없다. (zero-install) -
프로그램의 빠른 시작이 가능하다. (node resolution의 파일시스템 순회가 빨라진다.)
-
의존성 끌어올리기(hoisting)을 하지 않아서 유령 의존성 현상을 막을 수 있다.
-
zip 파일을 통해 패키지를 관리해서 빠진 의존성을 찾거나 변경된 것을 찾기 쉽다. 의존성 문제를 손쉽게 해결 가능하다.
Zero-installs를 사용했을 때, node_modules가 1.2GB 크기의 13만 5천개 파일로 구성되어있는 반면 Yarn PnP는 139MB의 천개 파일로 구성된다.
이러한 점 때문에 결과적으로 배포 시간을 단축시키는데 도움이 될 수 있다.
3. 사용법#
yarn이 설치되었다는 가정하에 먼저 아래와 같이 yarn의 버전을 berry로 변경한다.
yarn set version berry이렇게 하고 기존과 같이 yarn install을 해주면 node_modules가 사라지고 .yarn이라는 폴더가 생긴다. 그리고 그안에 패키지 정보를 담고 있는 .pnp.cjs 파일이 생기고 cache 디렉토리에 package들이 zip파일로 압축되어 있다.
정리#
아직 yarn berry는 제대로 써보지 않았지만, 다음 웹 프로젝트에 한번 적용해서 사용해보는게 좋을 것 같다는 생각이 들었다. 개발하다보면 패키지 의존성 문제나 버전 문제로 고생했던 경험을 누구나 가지고 있을 것이기 때문에, 이러한 문제를 회피하는데 yarn berry가 매우 도움될 것 같고, 그 외에도 여러가지 장점들이 있기 때문에 사용할 가치가 충분하다고 생각한다.
출처 :
![[Ykss]](/static/e1b6058af380e8a00f152aefa04db768/cbeb2/profile.jpg)