npm, yarn, pnpm

d_wwan·2023년 9월 18일
3

⭐️ npm?

npm은 세계 최대의 소프트웨어 레지스트리다. 모든 대륙의 오픈 소스 개발자가 npm을 사용하여 패키지를 공유하고 빌려 쓰고 있으며, 많은 조직에서 개인 개발을 관리할 때에도 npm을 사용한다.

npm의 구성요소

  1. 웹사이트
    • 패키지를 검색, 패키지의 액세스 관리, docs
  2. 명령줄 인터페이스(CLI)
    • 터미널에서 실행되는, 개발자과 npm과 상호 작용하는 방식
  3. 레지스트리
    • JavaScript 소프트웨어와 이를 둘러싼 메타 정보에 대한 대규모 공개 데이터베이스
    • 원하는 호환 가능 레지스트리를 사용하도록 npm을 구성할 수 있고, 다른 사람의 레지스트리를 사용하는 경우 해당 사용 약관이 적용된다.

npm에서 설정 가능한 부분들

  • 앱에 맞게 패키지를 조정
  • npx를 사용하여 패키지를 다운로드하지 않고 사용
  • 특정 타겟에게 코드 제한
  • 조직을 구성, 패키지 관리 가능
  • 여러 버전의 코드와 종속성 관리 가능
  • 비슷한 문제를 겪는 다른 개발자를 찾을 수 있다.

CLI commands ( 10.0.0 )

npm

  • npm access : 패키지에 대한 접근 수준 설정
  • npm adduser : 레지스트리 사용자 추가
  • npm audit : 보안 감사 실행
  • npm cache : 패키지 캐시 제어
  • npm help : 도움말
  • npm install : 설치
    • npm ci : node_mudules를 삭제하고 의존성을 한번에 설치
  • npm config : npm config파일 관리
  • npm dedupe : 중복 감소
  • npm root : npm 루트 표시
  • npm restart : 패키지 재시작
  • npm run-script : 임의의 패키지 스크립트 실행
  • npm search : 패키지 탐색
  • npm ls : 설치된 모든 것
  • npx : 패키지에서 명령만을 호출

저장 directories

local mode

  • 현재 프로젝트 디렉토리에 패키지를 설치하며, 디폴트 값이다.
    • ./node_modules, ./node_modules/.bin

global mode

  • 전역으로 참조 가능한 디렉토리에 설치
    • $npm_config_prefix/lib/node_modules, $npm_config_prefix/lib/node_modules/bin
    • -g or - -global

Develop

npm link

  • 현재 작업 중인 노드의 경로에 연결하여 변경할 때마다 재설치가 필요없도록 한다.

npm publish

  • 코드를 레지스트리에 업로드한다.

npm install

  • 모듈을 설치함

📀 yarn?

yarn은 프로젝트 관리자 겸 패키지 관리자다. npm과 같은 기능을 수행하나 종속성을 관리하는 측면과 무게 측면에서 npm보다 더 나은 패키지 매니저라고 한다. npm은 종속성을 순차적으로 설치하지만 yarn은 패키지를 동시에 가져오고 설치한다. (병렬)

CLI

  • yarn init : pacakage.json 생성
  • yarn or yarn install : package.json 파일 및 해당 종속성에 나열된 모든 모듈 설치
  • yarn add package_name@version : 특정 패키지의 특정 버전 설치
  • yarn add 주소 : 특정 저장소 내 패키지 설치
  • yarn gloabal add package_name : 전역 설치
  • yarn remove : 패키지 제거
  • yarn upgrade : 버전 업데이트
  • npm dedupe : npm과 같이 중복 삭제

이렇게만 보면 yarn이 npm의 상위 호환처럼 보이는데…차이점에 대해서 좀더 알아보자.

속도

yarn은 패키지를 캐시에 저장하며, 중복된 데이터는 다운로드하지 않는다. 또한 패키지를 병렬로 설치하기에 속도면에서 우수하다고 한다.

(최근에는 npm도 개선되어 크게 차이나지 않는다고 한다.

안정성 / 보안성

npm은 패키지가 설치될 때 자동으로 코드와 의존성을 실행할 수 있도록 한다.

이 과정에서 보장된 정책없이 등록한 패키지가 존재할 수 있다.

yarn은 yarn.lock이나 package.json으로부터 설치만 하며 (no 실행) , yarn.lock은 모든 디바이스에 같은 패키지를 설치하는 것을 보장한다.

무엇을 써야할까?

속도의 측면에선 npm의 개선으로 큰 차이가 없으나 병렬적인 패키지설치, 버전 관리의 편리함 등에선 yarn이 우세해 보인다. 일단 개발자의 관점에선 yarn을 쓰는게 맞아 보이는데…pnpm에 대해 알아보고 다시 이 이야기로 돌아오자.


💾 pnpm

node.js 16 major 이상부터 사용할 수 있는 패키지 매니저

  • 이 major부터는 패키지 매니징을 위해 Corepack을 제공하기 때문에 활성화가 필요하다
    brew install corepack
    
    corepack prepare pnpm@latest --activate
  • 설치 npm install -g pnpm

pnpm vs npm

npm의 플랫트리

npm flattened dependency tree를 통해 종속성을 관리한다.

이런 방식은 디스크를 덜 사용하지만 복잡한 node_modules구조를 야기한다.

반면 pnpm은 node_modules를 global on-disk Content-addressable-storage에 저장한다.

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가 생성된다.

🚨 주의사항

  1. 패키지가 자기 자신에 대한 import를 허용한다. foo 는 require('foo/package.json') 또는 import * as package from "foo/package.json" 를 할 수 있어야한다.

  2. 순환 심볼릭 링크를 피한다. 패키지의 의존성은 의존하는 패키지와 동일한 폴더에 있다. Node.js의 경우, 의존성이 패키지의 node_modules 내부에 있는지 또는 상위 디렉토리의 다른 node_modules 에 이 있는지 여부로 차이를 두지 않는다. 즉, pnmp는 의존성을 중복으로 설치하지 않고, 프로젝트 전체에서 공유하거나 재사용한다. 이렇게 하면 디스크 공간을 절약하고 빠른 의존성 설치 및 업데이트가 가능하다고 한다.

    ( 이렇게 이해하는게 맞나 모르겠다. )

이 방식으로 npm의 디스크 소모량을 개선할 수 있다. node_modules구조가 간단해지기 때문..!

또한 pnpm의 node_modules구조는 프로젝트의 package.json에 명시되지 않은 모듈을 사용할 수 없게 함으로써 의도되지 않은 버그를 피하는 것을 도와준다.

설치

pnpm은 package.json에 저장하지 않고 패키지를 설치하는 것을 허용하지 않는다. -prune커맨드로 관련없는 패키지를 삭제하는 것도 가능하다.

디렉토리 dependeincies

file: 접두사로 시작하고, 파일 시스템 내의 디렉토리를 가리킨다. npm처럼 pnpm도 이러한 의존성을 symlinks한다. npm과 달리 모든 dependencies를 설치하지는 않는다.


profile
세상 모든 사람들을 이해할 수 있는 날이 오기를

0개의 댓글