Skip to content

패키지 관리 도구 ​

패키지를 관리하는 도구는 엄청 많다.
가장 기본적인 npm부터 Yarn, pnpm까지.

패키지 관리가 중요한 이유는,
개인으로만 프로젝트를 진행한다면 상관없겠지만
다른 사람과 함께 개발해야 되기 때문에 패키지 관리가 필요하다.

어떤 사이트를 만들 때
나는 A, B 패키지를 사용하는데 리락쿠마라는 아이는 (ㅎ) C 패키지를 사용한다고 하자.
이때 발생하는 문제는 다음과 같다.

  1. 나는 C라는 패키지를 안 갖고 있으니 C라는 패키지를 사용하는 코드에서 오류가 날 거다.
  2. 서버는 A, B, C 패키지를 사용하고 있는 건지, 뭔지 아무것도 모르니 여기서도 오류가 날 거다.

그래서 내 컴퓨터 자체에 전역적으로 패키지를 설치하는 것보단,
해당 프로젝트 내에서만 사용할 패키지를 설치해서
package.json 파일에 내가 사용하는 패키지 정보가 추가되는 게 좋다.
그래야 남들도 해당 패키지를 설치해서 사용할 수 있을 테니 말이다.

이런 패키지 설치를 도와주는 Node.js는
자바스크립트를 브라우저 밖에서도 실행할 수 있게 해주는 런타임 환경이다.
원래 자바스크립트는 브라우저에서만 동작했는데,
Node.js 덕분에 서버든 파일이든 어디서든 동작할 수 있게 됐다.

자료구조에서 트리에 있는 각각의 데이터를 node라고 칭하지 않는가.
Node.js에서도 각각의 모듈들이 트리처럼 연결되어 있고,
이를 개별적으로 처리하기 때문에 Node.js라고 이름을 지은 거다.

지금부턴 패키지 관리자의 종류에 대해 알아보자.

npm ​

npm은 Node.js의 탄생과 함께 등장한 가장 오래되고 기본적인 패키지 관리자다.
npm install <패키지명> 명령어를 활용해
수많은 패키지를 프로젝트에 쉽게 추가하고 관리할 수 있다.

npm의 원리는 다음과 같다.
내가 Node.js를 설치하면 npm이라는 도구가 같이 설치되는데, 이게 바로 내장 패키지 관리자인 거다.
커맨드 창에다 npm 명령어를 실행하면 npm 레지스트리 서버에서 패키지 데이터를 가져와서 설치가 된다.

그 왜, 윈도우에서 무슨 프로그래밍 언어 공부하려고 하면
시스템 환경변수 편집해서 경로 추가하라고 하지 않는가.
거기서 경로 지정해서 내가 터미널에서 어떤 명령어를 치든 간에
빨리빨리 불러올 수 있도록 하는 거랑 비슷한 원리다.

Yarn ​

Yarn은 초기 npm의 느린 속도와 불안정한 의존성 관리 문제를 해결하기 위해
Facebook(현 Meta)에서 만든 패키지 관리자다.

원래 npm에는 package-lock.json이 없었다가 v5부터 생기기 시작했다고 한다.
그래서 이 전에는 패키지 버전에 lock을 걸고 싶었으면 Yarn을 사용해서
Yarn.lock에다가 패키지 버전을 관리해야 됐다.

만약 lock 파일이 없다면
누구는 A패키지의 1.0버전을 설치했는데,
누구는 A패키지의 1.2버전을 설치할 수 있다.

yarn.lock은 개발 환경과 배포 환경에서의 패키지 버전이 완벽하게 동일함을 보장한다고 한다.
지금이야 npm도 package-lock.json을 지원해서 별 차이가 없다고 하지만,
당시엔 Yarn이 훨씬 안정적이고 빨랐다고 한다.

npm과 Yarn의 차이 ​

옛날엔 npm과 Yarn의 차이가 컸다는데, 어떤 차이가 있던 걸까.

  1. 병렬 처리
    CPU랑 GPU 차이처럼 똑같다.
    npm은 패키지를 한 번에 하나씩 순차적으로 설치했는데
    yarn은 패키지를 동시에 병렬로 설치했다.
    그래서 npm 설치에 10분 걸리던 게 yarn으로는 2-3분 만에 끝났다고 한다.
  2. 캐싱 시스템
    npm은 같은 패키지를 또 설치하면 또 다운로드 받았는데,
    yarn은 한 번 받은 건 캐시에 저장해두고 재사용했다.
  3. 보안
    npm은 패키지를 설치할 때 그 패키지가 가져오는 다른 패키지들까지
    자동으로 실행해버렸는데, 이게 보안상 위험성을 갖고있었다.
  4. 버전 관리
    앞에서도 말했지만 npm은 따로 버전을 관리하지 않았기에
    사람마다, 서버마다 돌아가는 패키지 버전이 다른 위험성이 있었다.

이렇게 옛날엔 두 관리자가 갖고 있는 특성이 정말 천지차이였다고 한다.
하지만 지금은 npm도 많이 발전해서
병렬 처리도 하고, 캐싱도 하기에 거의 비슷한 수준이 됐다고 한다.

Yarn classic과 Yarn berry ​

그래서 현재는 오히려 yarn 버전에서의 차이가 있다고 한다.

Yarn berry는 2020년도에 완전히 새로 만든 NEW!! 버전인데,
얘는 PnP(Plug'n'Play) 방식이 핵심이다.

기존에는 node_modules 폴더에 패키지들을 쭈욱 풀어서 사용했는데,
Yarn berry는 zip 파일로 압축해서 .pnp.js 파일에서 경로를 관리한다.

그래서 이게 장점으로 작용하는 경우는 크게 두 가지가 있다.

  1. 보통 큰 회사들은 모노레포를 사용하는데, 이때 관리되는 패키지 다운 속도를 엄청 빠르게 해준다.
    참고로 모노레포란: 여러 프로젝트를 하나의 저장소에서 관리하는 방식이다. 웹사이트, 모바일앱, 공통 라이브러리 등 모든 것을 한 곳에서 관리하는걸 말한다.
  2. Zero Install 기능이 있어서, 패키지를 따로 설치할 필요 없이 클론만 하면 바로 실행이 가능하다.

반대로 단점은

  1. 패키지의 Zip 파일이 다 들어가다보니 git 저장소의 크기가 커진다.
  2. 기존 도구들과의 호환성 문제가 조금 있다고 한다.

pnpm ​

pnpm은 Performant Node Package Manager의 약자를 갖고 있다.
Performant란, 소프트웨어에서 효율적이고 성능이 좋다는 뜻이다.
performance랑은 또 다르게 기술 카테고리에서 해당 용어가 쓰이는 게 신기하다

아까 앞에서 패키지는 하나의 프로젝트에 설치하는 게 좋다고 하지 않았나.
내 컴 전체에 전역적으로 설치하면 설치 유무를 내 컴만 알지, 그 프로젝트는 모르니까.

근데 pnpm은 이 문제를 좀 다르게 해결한다.
패키지들을 전역 저장소에 한 번만 저장해두고,
각 프로젝트에서는 그 패키지들을 심볼릭 링크(바로가기 같은 기능)로 연결해서 사용하는 거다.

그래서 이미 다운로드된 패키지는 전역 저장소에서 빠르게 링크하여 설치하므로
설치 속도가 빠르고, 디스크 공간도 절약된다.
그래서 performant하다고 표현한 것 같다.

참고로 Yarn과 npm에서의 캐싱과 pnpm의 캐싱 방식 차이에 좀 집중해서 다시 정리해보자면,
전자는 각 프로젝트마다 node_modules에 복사본을 만들어서 관리하는거고
후자는 전역 저장소에 한 번만 저장해서 관리하는거다.

맺음말 ​

비하인드 ​

해당 레포 패키지 매니저를 yarn classic으로 썼는데,
패키지 설치할 때 되게 빠르단 기분이 들었었는데,
그냥 기분탓이었던걸로 ^^

참고 자료 ​