참고
Yarn Berry
NOTE
yarn berry는 node_modules없이 node를 사용할 수 있는 환경을 구축하게 해준다!
yarn v2 == yarn v2라고 생각하면된다.
npm, yarn, pnpm모두 패키지 매니저의 역할을 수행한다.
•
패키지의 의존성 관리
•
패키지 신뢰성 & 손상되지 않음을 보장
•
기능에 따라 여러 패키지의 그룹화
•
패키지 압축 해제
•
스크립트 실행
•
패키지 배포
Node.js환경의 패키지 매니저 분석
•
npm, yarn: node_modules 폴더에 의존성 설치
•
pnpm: 중첩된 node_modules 폴더에 의존성을 저장하는 방식을 개선하기 위해 도입
•
Yarn-berry(yarn v2): pnp(Plug’n’Play) 모드, node_modules가 없음
NPM의 문제점
NOTE
NPM은 Node.js 설치시에 기본으로 제공되어 범용적으로 사용되고 있으나, 비효율적이고 깨져있는 부분이 많다!
비효율적인 의존성 검색
NPM은 파일 시스템을 이용하여 의존성을 관리한다. node_modeules폴더를 이용하는 것이 특징인데 이렇게 관리했을 때, 의존성 검색은 비효율적으로 동작한다.
•
ex) /Users/toss/dev/toss-frontend-libraries 폴더에서 require()문을 이용하여 react패키지를 가져온다 가정하자.
•
라이브러리를 찾기 위해 순회하는 디렉토리 목록을 확인하려고 할 때 Node.js에서 제공하는 require.resolve.paths() 함수를 사용할 수 있다. 이 함수는 NPM이 검색하는 디렉토리의 목록을 반환한다.
•
머목록에서 확인할 수 있는것처럼 NPM은 패키지를 찾기 위해서 계속 상위 디렉토리의 node_modules 폴더를 검색한다. 따라서 패키지를 차지 못할 경우, readdir, stat과 같은 느린 IO호출이 반복된다.
•
TypeScript 4.0까지는 node_modules를 이용한 패키지 탐색이 너무 비효율적인 나머지, 패키지를 처음으로 import하기 전까지는 node_modules 내부의 정보를 찾아보지도 않기도 했다.
환경에 따라 달라지는 동작
NPM은 패키지를 찾지 못하면 상위 디렉토리의 node_modules폴더를 계속 탐색한다. 이 특성 때문에 어떤 의존성을 찾을 수 있는지는 해당 패키지의 상위 디렉토리 환경에 따라 달라진다.
•
ex) 상위 디렉토리가 어떤 Node_modules를 포함하고 있는지에 따라 의존성을 불러올 수 있기도하고 없기도 하다.
비효율적인 설치
NPM에서 구성하는 node_moudles 디렉토리 구조는 매우 큰 공간을 차지한다. 일반적으로 간단한 CLI 프로젝트도 수백 메가바이트의 node_modules 폴더가 필요하다. 용량만 많이 차지할 뿐 아니라 큰 node_modules 디렉토리 구조를 만들기 위해서는 많은 IO작업이 필요하다.
유령 의존성
NPM및 Yarn v1에서는 중복해서 설치되는 node_moduels를 아끼기 위해서 끌어올리기 기법을 사용한다. 의존성 트리거가 왼쪽의 모습을 하고 있다고 생각하자
•
왼쪽 트리에서 A/B 1.0이 2번씩 설치되므로 디스크 공간을 낭비한다. yarn v1에서는 디스크 공간을 바꾸기 위해 오른쪽처럼 바꾼다.
•
이렇게 끌어올리기에 따라 직접 의존하지 않은 라이브러리를 require()할 수 있는 현상을 유령 의존성이라고 한다. (package.json 의존성 수정에 따라 혼란스러워질 가능성이 높다.)
Yarn Berry의 장점 - Plug’n’Play(pnp)
NOTE
PnP는 기존의 node_modules 폴더를 사용하는 방식에서 벗어나 의존성을 효율적으로 관리하고 부팅시간을 단축시켜주는 방식이다!
npm install -g yarn
cd ../path/to/package
yarn set version berry
Bash
복사
Plug’n’Play 켜기
Plug'n'Play의 동작
zip 저장
cjs 파일
yarn berry에서는 node_moduels대신 의존성 lookup 파일인 .pnp.cjs를 생성한다.
•
.pnp.cjs 파일의 포함내용
◦
관련된 패키지 이름
◦
패키지 버전
◦
디스크에서의 위치…
yarn은 Node.js에서 제공하는 require()문의 동작을 덮어씀으로써 효율적으로 패키지를 검색할 수 있도록 한다.
Node.js앱을 실행 시 package.json의 scripts에 실행 스크립트를 등록해 사용한다. yarn으로 스크립트를 실행하면 PnP로 의존성을 자동으로 불러온다.
Zip 아카이브로 의존성을 관리할 수 있는데 이를 사용해서 없거나 필요없는 의존성을 쉽게 찾을 수 있다.
pnp 도입 결과
NOTE
의존성 검색할 때
•
더이상 node_modules 폴더를 순회할 필요가 없다.
•
.pnp.cjs 파일이 제공하는 자료구조를 이용하여 바로 의존성을 찾기 때문이다.
•
requre()에 걸리는 시간이 크게 단축되었다.
재현 가능성
•
패키지의 모든 의존성은 pnp.cjs 파일을 이용하여 관리되기 때문에 더 이상 외부 환경에 영향받지 않는다.
•
다양한 기기 및 CI 환경에서 require() 또는 import문의 동작이 동일해진다.
의존성을 설치할 때
•
node_modules 디렉토리 생성이 필요없어진다.
•
NPM이 설치하는 것처럼 같은 버전의 패키지가 여러 번 복사되어 설치시간을 단축할 수 있다.
•
이에 더해 Zerio-Install을 사용하면 대부분 라이브러리를 설치 없이 사용할 수 있다.
엄격한 의존성 관리
•
Yarn PnP는 node_modules에서와 같이 의존성을 끌어올리지 않는다.
의존성 검증
•
node_moduels를 사용하여 의존성을 관리했을 때에는 올바르게 의존성이 설치되지 못해서 의존성 폴더 전체를 지우고 다시 설치해야 하는 경우가 발생한다.
•
Yarn pnp에서는 zip파일을 이용하여 패키지를 관리하기 때문에 빠진 의존성을 찾거나 의존성 파일이 변경되었음을 찾기 쉽다.
•
이로서 의존성이 잘못되었을 때 쉽게 바로잡을 수 있습니다. 이로써 올바르게 의존성을 설치되는것을 보장할 수 있다.
Zero-Install
NOTE
위에서 Yarn Berry PnP의 장점들을 살펴보았는데 한발 더 나아가 의존성도 Git을 통해 관리할 수 있게된다는 장점이 있다.
yarn pnp는 의존성을 하나의 Zip파일로만 표현하기 때문에 의존성을 구성하는 파일의 숫자가 NPM만큼 많지가 않다.
•
ex) 일반적인 node_modules는 1.2GB, 13만 5천개의 파일
•
ex) Yarn PnP의 의존성 139MB, 2천개의 압축파일
의존성을 버전관리에 포함하면 많은 장점들이 생긴다.
•
새로 저장소를 복제하거나 브랜치를 바꾸어도 yarn install을 실행하지 않아도 된다.
•
CI에서 의존성을 설치하는 시간을 크게 절약할 수 있다.