npm은 세계 최대의 소프트웨어 레지스트리다. 모든 대륙의 오픈 소스 개발자가 npm을 사용하여 패키지를 공유하고 빌려 쓰고 있으며, 많은 조직에서 개인 개발을 관리할 때에도 npm을 사용한다.
npm
local mode
global mode
npm link
npm publish
npm install
yarn은 프로젝트 관리자 겸 패키지 관리자다. npm과 같은 기능을 수행하나 종속성을 관리하는 측면과 무게 측면에서 npm보다 더 나은 패키지 매니저라고 한다. npm은 종속성을 순차적으로 설치하지만 yarn은 패키지를 동시에 가져오고 설치한다. (병렬)
이렇게만 보면 yarn이 npm의 상위 호환처럼 보이는데…차이점에 대해서 좀더 알아보자.
yarn은 패키지를 캐시에 저장하며, 중복된 데이터는 다운로드하지 않는다. 또한 패키지를 병렬로 설치하기에 속도면에서 우수하다고 한다.
(최근에는 npm도 개선되어 크게 차이나지 않는다고 한다.
npm은 패키지가 설치될 때 자동으로 코드와 의존성을 실행할 수 있도록 한다.
이 과정에서 보장된 정책없이 등록한 패키지가 존재할 수 있다.
yarn은 yarn.lock이나 package.json으로부터 설치만 하며 (no 실행) , yarn.lock은 모든 디바이스에 같은 패키지를 설치하는 것을 보장한다.
속도의 측면에선 npm의 개선으로 큰 차이가 없으나 병렬적인 패키지설치, 버전 관리의 편리함 등에선 yarn이 우세해 보인다. 일단 개발자의 관점에선 yarn을 쓰는게 맞아 보이는데…pnpm에 대해 알아보고 다시 이 이야기로 돌아오자.
node.js 16 major 이상부터 사용할 수 있는 패키지 매니저
brew install corepack
corepack prepare pnpm@latest --activate
npm flattened dependency tree를 통해 종속성을 관리한다.
이런 방식은 디스크를 덜 사용하지만 복잡한 node_modules구조를 야기한다.
반면 pnpm은 node_modules를 global on-disk Content-addressable-storage에 저장한다.
대충 컨텐츠를 고유한 키로 저장하고 컨텐츠로 검색이 가능한 저장소
관리 방식은 Hard Link와 Symbolic Link
symlink된 node_modules
구조 | pnpm
pnpm의 node_modules 레이아웃은 심볼링 링크를 사용하여 의존성의 중첩구조를 생성한다. node_modules 안에 있는 모든 패키지의 모든 파일들은 CAS에 대한 Hard Link다! ( 포인터의 개념? )
node_modules
└── .pnpm
├── bar@1.0.0
│ └── node_modules
│ └── bar -> <store>/bar
│ ├── index.js
│ └── package.json
└── foo@1.0.0
└── node_modules
└── foo -> <store>/foo
├── index.js
└── package.json
bar@1.0.0에 의존하는 foo@1.0.0을 설치했다고 가정해보자.
pnpm은 foo와 bar을 둘다 node_modules에 하드링크한다.
node_modules의 유일한 실제파일이된다. ( foo, bar )
모든 패키지가 하드링크되면, 중첩된 의존성 그래프 구조를 구축하기위해 Symbolic Link가 생성된다.
🚨 주의사항
패키지가 자기 자신에 대한 import를 허용한다. foo
는 require('foo/package.json')
또는 import * as package from "foo/package.json"
를 할 수 있어야한다.
순환 심볼릭 링크를 피한다. 패키지의 의존성은 의존하는 패키지와 동일한 폴더에 있다. Node.js의 경우, 의존성이 패키지의 node_modules
내부에 있는지 또는 상위 디렉토리의 다른 node_modules
에 이 있는지 여부로 차이를 두지 않는다. 즉, pnmp는 의존성을 중복으로 설치하지 않고, 프로젝트 전체에서 공유하거나 재사용한다. 이렇게 하면 디스크 공간을 절약하고 빠른 의존성 설치 및 업데이트가 가능하다고 한다.
( 이렇게 이해하는게 맞나 모르겠다. )
이 방식으로 npm의 디스크 소모량을 개선할 수 있다. node_modules구조가 간단해지기 때문..!
또한 pnpm의 node_modules구조는 프로젝트의 package.json에 명시되지 않은 모듈을 사용할 수 없게 함으로써 의도되지 않은 버그를 피하는 것을 도와준다.
pnpm은 package.json에 저장하지 않고 패키지를 설치하는 것을 허용하지 않는다. -prune커맨드로 관련없는 패키지를 삭제하는 것도 가능하다.
file: 접두사로 시작하고, 파일 시스템 내의 디렉토리를 가리킨다. npm처럼 pnpm도 이러한 의존성을 symlinks한다. npm과 달리 모든 dependencies를 설치하지는 않는다.