npm은 범용적으로 많이 사용되나 비효율적인 측면이 많다.

npm은 파일 시스템을 사용해 의존성을 관리하는데, 예를들어 Users/test/dev/components라는 폴더에서 require로 lodash라는 패키지를 불러오는 상황을 가정할때
require.resolve.paths()를 사용해 검색하는데 npm은 해당 패키지를 찾기위해 아래처럼 계속 상위 디렉토리를 탐색한다.
일반적으로 이런 I/O 호출은 느리게 진행된다.
$ node
Welcome to Node.js v12.16.3.
Type ".help" for more information.
> require.resolve.paths('lodash')
[
'/Users/test/dev/components/repl/node_modules',
'/Users/test/dev/components/node_modules',
'/Users/test/node_modules',
'/Users/node_modules',
'/node_modules'
...
]
node_modules는 수백메가바이트 수준의 매우 큰 공간을 차지한다.
이로인해 복잡도는 올라가고 검증이 어렵다. 수백개의 패키지가 서로 의존한다면 node_modules의 디렉토리 구조는 매우 깊어질것이다.
npm 및 yarn v1은 중복설치를 막기위해 Hoisting기법을 사용한다.
아래 이미지를 보면 A(1.0)과 B(1.0)이 중복되기 때문에 Hoisting 하여 디스크 낭비를 방지한다.

하지만 이런 과정에서 기존에는 require할수 없었던 B(1.0)을 불러올수있게 된다.
따라서 package.json에 명시되지않은 B(1.0)을 package-1에서 가져올수있게되는 현상이 발생하고 이를 유령의존성이라 부른다.

yarn berry는 위 문제를 Plug 'n' Play 전략으로 해결한다.
yarn v1은 package.json 기반으로 의존 트리를 생성하고 디스크에 node_modules 구조를 만든다.
따라서 의존성 관리가 불완전한 파일시스템이 아닌 보다 안전한 의존성 관리를 위해 시작됐다.
npm최신 버전에서 yarn을 내려받고 버전을 berry로 설정하면 된다,
npm i -g yarn
cd ../path/to/some-package
yarn set version berry
yarn berry는 하위호환을 위해 패키지 단위로만 도입 할 수 있다
yarn berry는 node_modules를 생성하지않는 대신, .yarn/cache폴더에 의존성 정보가 저장되고, .pnp.cjs파일에 의존성을 찾을수있는 정보가 기록된다.
이는 디스크 I/O작업이 없이 빠르게 동작한다.

예를들어 react패키지는 .pnp.cjs파일에서 아래와 같이 나타난다
/* 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은 node가 제공하는 require문을 덮어씀으로 node명령어 대신 yarn node명령어를 사용해야 한다
$ yarn node
.yarn/cache폴더 내부에 각 의존성들은 zip파일로 관리된다.
이로인해
.pnp.cjs파일이 제공하는 자료구조를 이용해 바로 의존성 위치를 찾기때문..pnp.cjs파일로 관리되기때문에 외부환경에 영향을 받지않는다.node_modules에 비해 zip파일로 관리하기 때문에 용량이 매우 적고 git 으로 관리가능함.
이로 인한 장점으로
요약하자면
npm은 비효율적인 탐색, 의존성 중복으로 인해 매우 무겁고 복잡하여 의존성관리 및 검증이 힘들다.
yarn berry는 zip아카이브와 .pnp.cjs로 관리하기 때문에 순회 과정이 필요없고 매우 가볍고 의존성 관리 및 검증이 쉽다.
따라서 CI에서 많은 시간을 줄일수있고 의존성도 더 엄격하게 관리가 가능하다!
https://toss.tech/article/node-modules-and-yarn-berry
https://velog.io/@dev_jiminn/MonoRepo-with-Yarn-Berry