본문 바로가기

프로젝트 개발일지/프로젝트 세팅

yarn berry에 대해서 알아보자

yarn berry

yarn berry는 다들 한 번씩은 들어봤을 거 같다.

쉽게 말하자면 새로운 패키지 관리 시스템이다.

 

왜 요즘 npm을 사용하지 않고 yarn berry를 사용하려 하는가?에 대해서 알아보자.

 

npm

다음은 npm의 단점들이다.

 

파일 시스템을 이용해서 의존성을 관리하는 npmnode_modules 폴더를 이용한다.

처음 패키지를 import하는 경우, npm은 패키지를 찾기 위해서 계속 상위 디렉토리의 node_modules 폴더를 탐색하게 된다.

패키지를 찾지 못하면 계속해서 느린 I/O 작업이 일어나게 되고, 실패하기도 한다.

 

또, 각 패키지의 상위 디렉토리의 환경에 따라서 해당 의존성을 찾을 수 있는지가 달라진다.

따라서 일관성 있게 패키지를 불러올 수 없는 것이다.

 

하지만, 여기서 끝이 아니다.

node_modules를 한 번이라도 삭제 후 재설치해 본 사람은 알 것이다.

node_modules는 크기가 매우 큰 폴더이다.

이는 용량도 클 뿐만 아니라 I/O 작업도 상당히 많이 필요하다.

따라서, 속도 면에서 비효율적일 수밖에 없어진다.

 

 한편, 아래는 중복 패키지 설치를 위한 호이스팅 기법이다.

이렇게 호이스팅을 이용해서 직접 의존하고 있지 않은 라이브러리를 require()할 수 있는 현상을 유령 의존성이라고 한다.

위 그림의 경우 A 패키지의 유령 의존성은 B가 될 것이다.

만약 유령 의존성이 유지된다면, A 패키지를 삭제했을 때 B 패키지가 함께 사라질 수도 있는 것이다.

 

뿐만 아니라, 프로젝트를 진행하게 되면 node_modules는 용량이 크기 때문에 github에는 따로 올리지 않고 gitignore 파일에 담겨 올라가게 될 것이다.

내가 아닌 다른 팀원이 작업을 하게 된다면 매번 npm / yarn 명령어를 통해 해당 파일들을 재설치해야 하는 번거로움이 생길 수밖에 없다.

 

이런 문제들을 yarn berry가 해결했는데 이를 위해 Plug'n'Play 전략을 이용했다고 한다.

 

Plug'n'Play(PnP)

yarn v1은 package.json 파일을 통해서 의존성 트리를 생성하고, 디스크에 node_modules 디렉터리 구조를 만든다.

이렇게 관리하는 것보다 안전하게 패키지를 관리하기 위해서 PnP라는 개념을 바탕으로 등장하게 되었다.

 

Pnp, Plug and Play는 즉시 시작, 즉, 꽂기만 하면 사용할 수 있다 정도로 해석된다.

풀어서 얘기해보자면, 별도의 사용자 조작이나 프로그램 설치 없이 바로 사용할 수 있는 것이라고 보면 되겠다.

 

yarn berry는 npm과 다르게 node_modules를 생성하지 않고, .yarn/cache 폴더에 의존성 정보를 저장하고, .pnp.cjs 파일에 의존성을 찾을 수 있는 정보가 기록된다.

.pnp.cjs를 이용하면 디스크 I/O 없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 또 각 라이브러리의 위치는 어디인지 바로 알 수 있다.

/* react 패키지 중에서 */
["react", [
  /* npm:17.0.1 버전은 */
  ["npm:17.0.1", {
    /* 이 위치에 있고 */
    "packageLocation": "./.yarn/cache/react-npm-17.0.1-98658812fc-a76d86ec97.zip/node_modules/react/",
    /* 이 의존성들을 참조한다. */
    "packageDependencies": [
      ["loose-envify", "npm:1.4.0"],
      ["object-assign", "npm:4.1.1"]
    ],
  }]
]],

 

yarn pnp 시스템에서 각 의존성들은 zip 아카이브로 관리된다.

즉, 압축 파일로 관리한다는 것이다.

 

각 패키지는 버전마다 하나의 zip 아카이브만을 가지도록 되어 있어 중복 설치도 되지 않고, 용량도 상당히 아낄 수 있게 된다.

이렇게 하면 없는/필요 없는 의존성을 쉽게 찾을 수 있게 된다.

또한 해당 파일 내용 변경의 경우 체크섬과 비교해서 변경 여부도 쉽게 감지할 수 있다고 한다.

 

위에서 언급했던 문제 중 용량 문제로 github 상에 패키지 관련 파일들을 올리지 않는 문제도 한 번 더 자세히 알아보자.

yarn v2, 즉 yarn berry의 특징 중 하나인 zero-install에 대해서 이해하면 이 문제가 해결된다는 것을 바로 알 수 있을 것이다.

 

이는, 의존성도 git 등을 사용해서 버전 관리를 할 수 있다는 것이다.

yarn PnP는 압축 파일로 의존성을 관리하기 때문에 용량과 파일 개수가 node_modules에 비해 훨씬 작다.

그래서, 이 의존성 관련 압축 파일들을 원격 저장소에 업로드를 할 수 있게 되고, 작업 시 추가적인 yarn / npm 설치 없이 프로젝트를 바로 실행할 수 있게 되는 것이다.

 

현재 진행 중인 프로젝트 TIFY에서도 yarn berry로 의존성을 관리하고 있는데, 나는 처음으로 npm 대신 yarn berry 방식을 쓰는 것이다.

써보니까 npm 방식보다 속도 면에서 확실히 빠른 것이 느껴지고, zero-install을 통해서 의존성 관리를 하기 때문에 별도의 패키지 설치 없이 pull만 하면 바로 쓸 수 있다는 게 엄청 큰 장점으로 느껴졌다.

 

앞으로 프로젝트를 진행한다면 꼭 yarn berry를 사용해서 개발해야겠다고 느꼈다.

 

참고 자료

https://toss.tech/article/node-modules-and-yarn-berry

https://namu.wiki/w/Plug%20%26%20Play

https://heeyeonjeong.tistory.com/117