Flab 과정을 들으면서 멘토님이 나에게 패키지 매니저에 대해 질문했는데 제대로 답을 하지 못했었다..;;
써보기만 했지 그것의 개념들은 잘 알지 못한 상황이어서 멘토님께서 공부하기 좋은 아티클들을 주셨다. 해당 아티클을 보고 정리한 내용들을 블로그에 작성해보려고 한다! 밑에 참고한 아티클의 링크를 작성해놓았습니다.
짧막한 Yarn Berry 설명
Yarn v1의 주요 개발자 Maël Nison 씨가 만듦.
2020년 1월 25일부터 정식 버전(v2)가 출시
기존의 “깨져있는” NPM 패키지 관리 시스템을 혁신적으로 개선함.
1. NPM의 문제점
- 비효율적인 의존성 검색
- 패키지를 찾기 위해 상위 디렉토리에서 하위로 파일을 탐색함
- 그 과정에서 잦은 디스크 I/O가 발생
- 패키지를 찾기 위해 상위 디렉토리에서 하위로 파일을 탐색함
- 환경에 따라 달라지는 동작
- 패키지 찾지 못하면 상위 폴더를 계속 탐색
- 때문에 상위 디렉토리 환경에 따라 탐색 여부가 갈림
- 상위 디렉토리가 어떤 node_modules를 포함하고 있는지에 따라 의존성을 불러올 수 있기도 하고, 없기도 함. 다른 버전의 의존성을 잘못 불러올 수 있는 여지도 존재
- 패키지 찾지 못하면 상위 폴더를 계속 탐색
- 비효율적인 설치
- 매우 큰 공간 차지
- 유령 의존성
- Npm, yarn v1에서 중복 설치되는 node_modules 아끼기위해 호이스팅 사용

왼쪽에서 A,B 패키지는 두번 설치되어 디스크 공간을 낭비함.
때문에 오른쪽 처럼 중복 설치를 막음.
하지만 이렇게 호이스팅을 하면서 직접 B 라이브러리를 호출할수 있게 되었는데
⇒ 직접 의존하지 않는 라이브러리를 require() 할 수 있는 현상 을 유령 의존성이라고 함
내가 직접 설치/명시하지 않은 라이브러리(의존성)를 코드에서 쓸 수 있는 현상
(하지만 사실은 “다른 라이브러리”가 그걸 설치해서, node_modules에 “우연히” 들어와 있기 때문)
문제점
- 내 package.json엔 없는 라이브러리가
- “이 프로젝트에 뭐가 필요한지” 정확하게 알 수 없다
- 실제로 내 코드에서 사용될 수 있으니,
- 예측불가 에러 발생
- 내가 직접 설치한 게 아니기 때문에,
- 만약 A라는 라이브러리가 패키지에서 빠지거나 버전이 바뀌면
- (ex. npm uninstall A, yarn remove A)
- 나도 모르게 lodash가 node_modules에서 사라져버림
- → 갑자기 “Cannot find module 'lodash'” 에러 토해냄
2. Plug'n'Play (PnP)
위 문제점을 해당 전략으로 해결함.
yarn v1은 package.json 파일을 기반으로 의존성 트리를 생성
→ 디스크에 node_modules 디렉토리 구조를 만듬
But , node_modules 파일 시스템으로 관리되는 의존성은 깨지기 쉬움.
⇒ 근본적으로 안전하게 의존성을 관리할수 없는지 ?!
Plug'n'Play 설치 모드에서 yarn install 로 의존성을 설치했을때
- yarn berry는 node_modules를 생성하지 않음.
- .yarn/cache 폴더에 의존성 정보가 저장
- zip 으로 묶인 라이브러리가 저장됨
- ZipFS (Zip Filesystem)node_modules처럼 폴더에 쫙 풀지 않고 버전별로 압축보관하는것.
- zip 파일을 마치 파일처럼 다루는 파일 시스템?
- 장점
- 디렉토리 구조 생성할 필요가 없어 설치가 신속히 완료됨
- 패키지 하나마다 .zip으로 압축 → 중복 설치가 없음, 차지하는 용량이 적음
- 파일 수가 많지 않아 변경 사항 감지 & 삭제하는 작업이 빨라짐.
- zip 으로 묶인 라이브러리가 저장됨
- .pnp.cjs 파일에 의존성을 찾을 수 있는 정보가 기록됨.
- .pnp.cjs 를 이용하면 디스크 I/O 없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 각 라이브러리는 어디에 위치하는지를 바로 알 수 있음.
- 이게 왜 좋은건지?
- 기존 방식 (node_modules)
- 패키지 import할 때, Node.js는실제로 디스크의 폴더/파일을 계속 뒤져봐야 함.
- “이 폴더에 있나? 저 폴더에 있나?”
- 즉, 매번 디스크 I/O 발생 (속도 느림)
- PnP 방식(.pnp.cjs 파일)
- 의존성, 패키지 위치 정보가
- “한 파일(.pnp.cjs)에 깔끔하게 Map 형태로 정리”
- Node.js가 .pnp.cjs 파일 “딱 한 번”만 읽고,
- 그다음부터는 메모리에서 바로바로 패키지 위치를 찾음.
- 그래서 import/require 할 때 디스크 I/O가 거의 없음
- (필요한 정보 이미 메모리에 있기 때문)
- 기존 방식 (node_modules)
3. Plug'n'Play 도입 결과
- 의존성 검색
- 더이상 node_modules 폴더를 순회할 필요 X
- .pnp.cjs 파일이 제공하는 자료구조를 이용 → 바로 의존성의 위치를 찾음.
- require() 에 걸리는 시간이 단축됨.
- 재현 가능성
- 패키지의 모든 의존성은 .pnp.cjs 파일을 이용하여 관리
- ⇒ 더이상 외부 환경에 영향 받지 않음.
- 의존성 설치
- 의존성 설치를 위해 깊은 node_modules 디렉토리를 생성하지 않아도 됨.
- 설치시간을 극단적으로 단축
- Zero-install 사용시 라이브러리 설치 없이 사용 가능
- 의존성 관리
- node_modules에서와 같이 의존성을 끌어올리지 않음
- 각 패키지들은 자신이 package.json에 기술하는 의존성에만 접근할 수 있음
- ⇒ 예기치 못한 버그를 쉽게 일으키던 유령 의존성 현상을 막을 수 있음.
- node_modules에서와 같이 의존성을 끌어올리지 않음
- 의존성 검증
- node_modules를 사용하여 의존성을 관리했을 때
- 올바르게 의존성이 설치되지 못해서 의존성 폴더 전체를 지우고 다시 설치해야 하는 경우가 발생하고는 했음
- yarn PnP에서는 Zip 파일을 이용하여 패키지를 관리
- 빠진 의존성을 찾거나 의존성 파일이 변경되었음을 찾기 쉬움.
- node_modules를 사용하여 의존성을 관리했을 때
Reference
https://toss.tech/article/lightning-talks-package-manager
패키지 매니저의 과거, 토스의 선택, 그리고 미래
토스는 왜 패키지 매니저로 Yarn을 선택했을까요? 이번 라이트닝 토크에서는 JavaScript의 패키지 매니저, 동작 방식, 그리고 토스의 선택과 앞으로의 방향성에 대해 이야기해 보려고 해요.
toss.tech
https://toss.tech/article/node-modules-and-yarn-berry
node_modules로부터 우리를 구원해 줄 Yarn Berry
토스 프론트엔드 레포지토리 대부분에서 사용하고 있는 패키지 매니저 Yarn Berry. 채택하게 된 배경과 사용하면서 좋았던 점을 공유합니다.
toss.tech
https://engineering.ab180.co/stories/yarn-to-pnpm
Yarn 대신 pnpm으로 넘어간 3가지 이유
패키지 매니저를 바꾸고 1년 동안 사용해보며 든 생각들
engineering.ab180.co
'공부 > 기술 개념 정리' 카테고리의 다른 글
| React 와 Vue 비교하기 (1) | 2026.01.29 |
|---|---|
| 단방향 vs 양방향 상태관리: React와 Vue의 핵심 차이 (0) | 2026.01.29 |
| 관심사 분리란? (SoC, separation of concerns) (0) | 2025.12.22 |
| OAuth 프로토콜 (7) | 2025.06.27 |
| 패키지 매니저의 정의와 차이 (yarn, pnpm, npm) (0) | 2025.06.27 |