나도! Yarn Berry 적용해볼래!

npm으로 프로젝트를 진행 중 Yarn Berry를 도입하게 되었다.
새로운 패키지 관리 시스템을 도입하게 된 배경과 과정 등을 정리해본다.

패키지 매니저란?

npm에 업로드된 노드 모듈을 패키지라고 하는데, 다양한 자바스크립트 프로그램이 패키지라는 이름으로 npm에 등록되어 있고, 패키지가 다른 패키지를 사용할 경우 의존 관계를 가지기도 한다.
이러한 패키지들을 사용하기 위해서는 다운로드, 설치, 업데이트, 의존성 관리, 제거 등 복잡한 상황들이 많이 생기는데
패키지 매니저는 이러한 과정들을 자동화하여 편리하고 안전하게 수행할 수 있도록 해준다.



npmyarn(v1)은 어떤 점이 다른가?

그 동안은 npm으로만 써왔는데, 이유는 딱히.. 처음 접한 것이 npm 이었다는 것?! yarn berry로 변경하면서 npmyarn의 차이를 찾아보았다

node 개발 환경에서는 패키지 매니저로 npm 또는 yarn을 사용하는데,
개발에 있어서 npmyarn, 이 둘의 차이는 크게 없다고 한다.

yarnnpm의 부족한 부분들을 개선하기 위해 Facebook에서 개발되었다. Yarnnpm이 사용하는 동일한 npm 구조에 의존한다. 따라서 패키지의 레지스트리에 대한 것은 바뀌지 않았고, 설치 절차가 바뀌었다고 생각하면 된다.

npm의 부족한 부분들을 개선하기 위해 나온 yarn!

  • npm이 먼저 나왔기 때문에 yarn 보다는 다운로드 수 및 점유율 측면에서 앞설 수 있고
  • yarnnpm의 부족한 점들이 개선되었다

는 점이 다른 점이라고 할 수 있겠다.


그럼 어떤 점이 개선되었을까?

  1. 속도가 더 빠르다
  2. 보안성이 좋다.


그럼 Yarn Berry(=yarn(v2))는 뭐야?

npm의 부족한 부분들을 개선하기 위해 나온 yarn(v1)이지만,
npmyarn(v1)의 공통적인 문제점이 있었는데..

npm 문제점


1) 비효율적인 의존성 검색

npm은 파일 시스템을 이용하여 의존성을 관리하는데 node-modules 폴더를 이용하는 것이 특징이다. 하지만 이렇게 관리하면 의존성 검색은 비효율적으로 동작한다..😱
npm은 패키지를 찾기 위해 계속 상위 디렉토리의 node-modules 폴더를 탐색하는데, 바로 찾지 못할수록 느린 I/O 호출이 반복된다.. 경우에 따라서는 I/O 호출이 실패하기도..😱😱

2) 환경에 따라 달라지는 동작

npm은 패키지를 찾지 못하면 상위 디렉토리의 node-modules 폴더를 계속 검색하는데, 이로 인해 해당 패키지의 상위 디렉토리 환경에 따라 동작이 변하게 된다. 이럴 경우 해당 상황을 재현하기 까다로워지기 때문에 환경에 따라 동작이 변하는 것은 나쁜 징조이다..😥

3) 비효율적인 설치

간단한 패키지를 몇 개 설치하지 않아도 node-modules 폴더는 매우 거대해진다. 게다가 next.js 등과 같이 다양한 기능을 제공하는 프레임워크, 라이브러리를 사용하게 된다면 메가에서 기가 단위의 디스크 용량을 사용하게 될 것이다.. (현재 내 플젝은 next...)
그리고 이렇게 거대해진 node-modules 폴더를 탐색하려면 많은 I/O 작업이 필요하니.. 말해뭐해..ㅠ

게다가 이렇게 거대해진 node-modules 폴더는 복잡하기 때문에 설치가 유효한지 검증하기 어렵다..
결국 이런 구조에서 의존성이 잘 설치되어 있는지 검증하려먼 많은 수의 I/O 호출이 필요..
이런 문제로 인해 yarn(v1)이나 npm은 기본적인 의존성 트리의 유효성까지만 검증하고, 각 패키지의 내용이 올바른지는 확인하지 않는다 😱

4) 유령 의존성(Phantom Dependency)

yarn(v1)이나 npm은 중복해서 설치되는 node-modules를 아끼기 위해 끌어올리기(Hoisting) 기법을 사용한다.

이렇게 끌어올리기에 따라 직접 의존하고 있지 않은 라이브러리를 require() 할 수 있는 현상을 유령 의존성(Phantom Dependency)이라고 부르는데,
유령 의존성 현상이 발생할 때, package.json에 명시하지 않은 라이브러리를 조용히 사용할 수 있게 된다. 또는 다른 의존성을 제거할 때 소리없이 같이 사라지기도 해서 의존성 관리 시스템을 혼란스럽게 한다..


Plug’n’Play (PnP)

Yarn Berry(=yarn(v2))는 pnp라는 개념을 도입해서 이런 문제들을 해결한다.

  • node-modules의 성능 문제
  • 비효율적인 호출
  • node-modules의 비효율적인 구조 등등

Plug’n’Play 적용하기

yarn2 에서는 비효율적인 node_modules대신에 .pnp.js라는 파일을 생성한다

package-lock.json 삭제하고

yarn 설치하기!

npm install -g yarn

Zero-Install

Yarn PnP은 의존성을 압축 파일로 관리하기 때문에 의존성의 용량이 작다. 또한 각 의존성은 하나의 Zip 파일로만 표현되기 때문에 의존성을 구성하는 파일의 숫자가 npm만큼 많지 않다.

이처럼 용량과 파일의 숫자가 적기 때문에 Yarn Berry를 사용하면 의존성을 Git으로 관리할 수 있는데, 이렇게 Yarn Berry에서 의존성을 버전 관리에 포함하는 것을 Zero-Install이라고 한다. Zero-Install을 사용하게 되면,

1) 새로 저장소를 복제하거나 브랜치를 바꾸었다고 해서 yarn install을 실행하지 않아도 된다.

다른 의존성을 사용하는 곳으로 브랜치를 변경했을 때, 잊지 않고 의존성을 설치해주어야 했고, 경우에 따라 잘못된 의존성 버전이 사용되어 알 수 없는 에러가 발생하기도 했는데, Zero-Install을 사용하면 이런 문제들이 해결된다.

2) CI에서 의존성 설치하는 시간을 크게 절약할 수 있다.

  • Zero-Install을 사용하면 Git Clone으로 저장소를 복제했을 때 의존성들이 바로 사용 가능한 상태가 되어, 의존성을 설치할 필요가 없다.
    이로 인해 CI 시간을 크게 절약할 수 있다는 장점이 있다.

.gitignore 파일 설정

# Zero-Installs 를 사용할 때
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

이렇게 공부하고 실제 npm에서 yarn berry로 변경하면서 크게 어려운 점은 없었던 것 같다. (워낙 자료들이 훌륭해서..ㅎㅎ)
그리고 너낌상이지만 불필요한 npm i 을 하지 않아서 좋았고,
불필요한 파일들이 설치되지 않아서 보다 가벼운? 느낌이었다.


그리고.. 사실 yarn berry로 변경하게 된 이유는, 프엔 동료가 제안해서 해보자!하는 마음으로 시작했는데..
그 프엔 동료는 이런 것들을 너무나 잘 알고 아는 것도 많다!👍👍
덕분에 이것저것 적용해보고 공부하고 테스트해 볼 수 있는 기회가 많아져서 좋다!!! 너무나도!!👏👏
나도 보다 시야를 넓혀서 제안도 해보고 적용도 해보고 싶다!

나의 시야야! 넓어져랏!ㅎ 🤣🤣



참고
토스: node_modules로부터 우리를 구원해 줄 Yarn Berry

원티드: yarn berry 적용기

좋은 웹페이지 즐겨찾기