Yarn Berry

이가리·2023년 2월 13일
1
post-thumbnail

프로젝트 관리를 위해 yarn berry를 도입하게 됐다. 여러명이 각자 작업을 진행하다보니 npm과 yarn 커맨드를 섞어 사용하게 되면서 package-lock.json과 yarn.lock 파일이 충돌..
새로운 분들이 오시고 패키지 관리자를 yarn으로 통일 + berry로 세팅하게 되었다. 세팅에 참여하지 못해 혼자 정리해보기로 했다!

Yarn

🐈‍ 고양이 🐈‍ 가 귀엽구요

https://engineering.fb.com/2016/10/11/web/yarn-a-new-package-manager-for-javascript/

Node.js를 위한 새로운 패키지 관리 시스템으로 빠르고 안정적이며 안전하게 종속성 관리를 할 수 있다.

2016년 페이스북에서 개발, 리액트로 프로젝트를 진행하며 겪었던 어려움을 해결하기 위해 개발되었다고 한다. 아무래도 npm의 단점 때문에 나온 배경 때문인지 속도, 안정성 측면에서 npm보다 향상되었다고 한다.

속도

yarn은 다운받은 패키지 데이터를 캐시(cache)에 저장하여, 중복된 데이터는 다운로드하지않고,
캐시에 저장된 파일을 활용함으로써 이론적으로 npm에 비해 패키지 설치속도가 빠르다. 또한 여러개의 패키지를 설치할 때 병렬로 처리하기 때문에 performance와 speed가 증가 된다. (npm은 순차적이라고 함)

안정성/보안성

npm은 패키지가 설치될 때 자동으로 코드와 의존성을 실행할 수 있도록 허용했다. 편리한 기능이지만 안정성을 위협할 수 있다. 특히나 보장된 정책 없이 등록한 패키지가 존재할 수 있다는 점에서 위험도가 높다.

반면 yarn은 yarn.lock이나 package.json으로 부터 설치만 하며, yarn.lock은
모든 디바이스에 같은 패키지를 설치하는 것을 보장하기 때문에 버전의 차이로 인해 생기는 버그를 방지해줄 수 있다.

현재는 npm도 많이 발전했고 단점도 보완했기 때문에 큰 차이는 없다고 한다.

Homebrew를 통해 설치할 수 있고, yarn 패키지 자체는 로컬 PC 내 global package 공간에 저장되어 커맨드를 통해 실행할 수 있다.
즉, Homebrew를 이용한 설치 이후에는 어느 디렉토리에서든 yarn을 쓸 수 있다는 말!

yarn add ...
yarn remove ...

그럼 yarn classic과 yarn berry 이름말고 뭐가 달라?

yarn berry는 yarn2의 프로젝트 이름으로 기존의 classic과 다르게 작동해 아예 다른 이름으로 지정한 게 아닌가 싶다!

주요 차이점은 PnP(Plub'n'Play)로 yarn berry를 쓰는 가장 큰 이유일 것 같다.


Plug'n'Play가 나온 이유

yarn은 package.json 파일을 기반으로 의존성 트리를 생성하고 디스크에 node_modules 디렉토리 구조를 만든다. 종속성 트리에 대해 알아야 할 정보를 모두 알고 있고, 설치하기도 한다.

그렇다면 패키지가 있는 위치를 찾는 게 꼭 노드에 달려 있어야할까? 그 대신 인터프리터에 디스크의 패키지 위치를 알리고 패키지와 패키지 버전 간의 종속성을 관리하는 것이 패키지 관리자의 역할이여야 하지 않을까? 패키지 매니저가 실수가 잦은 Node 내장 의존성 관리 시스템을 사용해야 할까? 패키지 매니저들이 노드 모듈 디렉토리 구조를 짜는 것에 그치지 않고 보다 근본적으로 안전하게 의존성을 관리하면 어떨까?

이 생각에서 출발!

동작 방법

yarn install 로 의존성 설치 시 기존의 yarn과 다르게 동작된다.
node_modules를 생성하지 않고, .yarn/cache 폴더에 의존성의 정보가 저장되고 .pnp.cjs 파일에 의존성의 정보가 기록된다. 이를 이용하면 디스크에 I/O 없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 그 위치 또한 바로 알 수 있다.

Node.js가 제공하는 require()의 동작을 덮어씀으로 효율적으로 패키지를 찾을 수 있게 된다. 이 덕에 PnP API를 이용해 의존성 관리를 하고 있을 때는 node 명령어 대신 yarn node를 사용해야 한다.

일반적으로 Node.js 앱을 실행할 때 package.json scripts에 실행 스크립트를 등록해 사용하게 되는데, yarn classic에서 사용하던 것처럼 yarn으로 스크립트를 실행하기만 하면 자동으로 PnP 의존성을 불러온다.

ZipFS (Zip Filesystem)

PnP 시스템에서 각 의존성은 Zip 아카이브로 관리된다. 예를 들어 Recoil은 recoil-npm-(버전)-9a0edbd2b9-c69105dd7d.zip과 같은 압축 파일로 관리된다.
이후, .pnp.cjs 파일이 지정하는 바에 따라 동적으로 Zip 아카이브의 내용이 참조되게 된다.

장점

  1. node_modules 디렉토리 구조가 생성되지 않게 되니 신속한 설치가 가능
  2. 각 패키지는 버전마다 하나의 Zip 아카이브만을 가진다.(중복 설치가 되지 않음) 또한 Zip 아카이브가 압축되어 있음을 고려하면 스토리지 용량을 아낄 수 있다.
  3. 의존성을 구성하는 파일의 수가 많지 않아 변경 사항이나 삭제 작업 적용이 빠르다. 필요없는 의존성을 쉽게 찾을 수 있다.

Zero-install

의존성도 git을 이용해 버전 관리를 하면 어떨까?

yarn PnP는 압축 파일로 의존성을 관리하기 때문에 용량이 적고, 하나의 Zip파일로만 표현되기 때문에 의존성 구성이 npm만큼 많지 않다.
이처럼 용량과 파일의 숫자가 적어져 git으로 관리할 수 있게 되는 것. 이렇게 의존성을 버전 관리에 포함하는 것을 Zero-install이라고 부른다.

장점

  1. yarn install을 실행하지 않아도 된다. repository 복제, 브랜치 변경 시 yarn install을 사용하면 경우에 따라 잘못된 의존성 버전이 사용되며 에러가 발생하기도 하는데 이 문제가 완전 해결!
  2. CI에서 의존성 설치 시간을 크게 절약할 수 있다.

도입 후

음.. 사실 크게 와닿는 점은 없다..😅 좀 더 써봐야 알겠거나.. 초반 작업 시 도입했었다면 더 와닿았을까? 지금은 업데이트 된 프로젝트를 pull 받을 때 yarn install을 실행하지 않아도 된다는 점 정도..

npm과 yarn을 동시에 사용하게 되니 lock 파일이 두 개가 되고 의존성 버전 설치 시간이라거나 버전 불일치로 인한 오류가 발생하기도 했는데, 의논해서 하나만 선택해 사용하는 것이 좋겠다.


참고

https://yarnpkg.com/getting-started
https://toss.tech/article/node-modules-and-yarn-berry
https://helloinyong.tistory.com/341

profile
절대로 할 수 있음

0개의 댓글