node 패키지 매니저 (npm, yarn , yarn berry)

59INU·2022년 4월 10일
1
post-thumbnail

yarn berry를 주로 사용하고 있는데 패키지매니저 간 차이와 히스토리를 정리해본 적 없는 것 같아서 정리함.

npm

yarn과의 비교를 위해 초창기 문제점들을 나열하나 실제로 현재는 열거된 문제 중 다수가 보완/개선되어 yarn 1과 큰 차이를 보이지 않는 경우가 많다. 다만 yarn은 당시 npm의 문제점들을 보완하기 위해 탄생한 것이었으므로 비교를 위해 해당 특징들을 씀.

속도

패키지 설치 실행 시 순차적으로 npm 레지스트리에서 가져와 설치하므로 비교적 그 속도가 느리다.

보안

설치하고자 하는 패키지A가 내부적으로 또 다른 패키지B에 의존 관계를 가질 때, npm은 이 패키지를 자동으로 그 즉시 설치한다. 패키지 하위 호환 범위의 버전 변경에서 문제가 있는 코드가 포함되어 있다면 위험에 그대로 노출되는 셈.

semver 와 버전 업데이트

npm은 semver 규칙에 의거하여 자동으로 패키지들을 업데이트한다. 하나의 패키지에 대하여 업데이트를 실행할 때 패키지 내부 의존성 트리에서 semver에 의해 의도하지 않은 거대한 양의 업데이트가 동반되는 것도 가능한 시나리오.

“works on my machine”

npm 5 이후 package-lock.json 파일 자동 생성을 지원했으나 그 이전에는 semver 기반 설치와 중복 패키지 제거(merge) 로직 등, 패키지 설치 순서나 시점에 따라 설치 결과인 node_modules의 파일 구조가 정해지는 비결정론적 방식이었다. 이로 인해 서버에 배포된 프로젝트와 개발자 로컬 환경서의 프로젝트의 패키지 설치 파일이 서로 다르거나, 동일한 package.json 파일을 공유하고 있는 개발자끼리도 로컬에 설치된 패키지가 서로 다른 상황에서 버그를 찾아야하는 혼란을 야기하기도 했다. - "제 컴퓨터에선 되는데용?"

yarn 1

속도

패키지 설치 시 병렬 실행을 지원하므로 설치 속도가 빠르다

보안

오로지 yarn.lock, package.json 파일에 저장된 패키지를 설치하며, 코드 실행 전 checksum 으로 패키지 무결성을 검사하여 보안 이슈를 개선했다. (하지만 npm과 동일하게 I/O 호출을 통해 node_modules 폴더를 관리하던 yarn1에서 패키지 내용을 검증하진 않았다는 데 checksum은 뭘 검사하는겨. 이전에 설치된 것과 같은 패키지가 맞는지만 해시로 체크한다는 건가)

패키지 버전 관리

yarn.lock 파일을 생성하여 이곳에 기록된 버전에 의거하여 이후 패키지를 설치하므로 모든 디바이스에서 동일한 버전의 패키지가 설치될 것을 보장한다.

캐시

패키지 설치 시 레지스트리에서 받아온 패키지 데이터를 로컬 캐시에 저장한다. 이로 인해 한 번 설치했던 패키지를 재설치할 때에는 레지스트리 대신 로컬 캐시를 참조하므로 속도가 빠르고 오프라인에서도 설치가 가능하지만 반대 급부로 디스크 메모리 사용량이 크다.

공통된 문제점

거대한 node_modules

  • 비싸고 비효울적인 I/O 기반의 설치 과정 및 탐색
  • 거대한 깊이와 복잡한 구조
  • 보증하기 어렵고 불안한 동작

유령 의존성

  • 패키지 중복 제거 전략으로 등장한 호이스팅으로 인해, 직접 의존 관계가 없는 패키지를 직접 임포트 할 수 있는 혼란과 충격의 결과물

plun'n'play

node_modules를 만들지 않는다.

  1. 레지스트리에서 가져온 패키지 정보를 .zip 형태로 압축해 ./yarn/cache 폴더에 저장한다.
  1. 해당 데이터를 가리키는 (매핑) 메타 데이터를 pnp.cjs 파일에 저장한다.
  • 해당 패키지가 가지는 의존성 정보
  • 패키지들의 연결 방식
  • 패키지의 저장 위치

특징

  • 로컬 캐시에 저장한 데이터를 node_modules로 옮겨오던 사치스러운 I/O 작업을 수행하지 않는다
  • 프로젝트 내에 직접 캐시 폴더를 생성하고 이 폴더가 존재하는 이상 설치 과정 없이 실행이 가능해진다.
  • 각 패키지 데이터는 캐시 폴더 안에 존재하며, 경로를 매핑해주는 hardLink 로 연결될 뿐이므로
    • 중첩 폴더 구조에서 중복 패키지 제거를 위해 발생했던 유령 의존성 문제에서 해방된다.
    • 비효율적인 재귀 탐색 없이 명시된 경로로 바로 접근할 수 있다.
profile
개랑 사는 개발자

0개의 댓글