sharingStorage

[패키지 매니저] npm, yarn, pnpm, yarn-berry 본문

Front-End

[패키지 매니저] npm, yarn, pnpm, yarn-berry

Anstrengung 2023. 4. 14. 13:48

Package Manager

패키지 매니저란?

 패키지를 관리하는 작업을 자동화, 안전처리 하기 위해 사용되는 도구

패키지 관리란 ?

 프로젝트가 의존하고 있는 패키지를 효과적으로 설치, 관리, 갱신, 삭제하는 작업

패키지 매니저가 필요한 이유 ? 

어떤 패키지가 동작하기 위해서 필수적으로 필요한 다른 패키지를 의존성(dependency)라고 하는데 이는 수동으로 관리하기 불가능하기 때문에 각각 패키지가 자신의 의존성 정보를 가지게 하여 패키지 매니저가 자동으로 설치해준다.

 

패키지는 코드의 배포를 위해서 사용되는 코드 묶음이며 일반적으로 라이브러리, 실행파일, 컴파일한 binary, 환경설정(configuration)정보, 의존성 정보 등을 포함한다. 

 

자바스크립트 패키지 매니저

프론트엔드 개발자가 가장 흔히 볼 수 있는 npm, yarn이 바로 자바스크립트 패키지 매니저다. 

대부분의 자바스크립트 패키지 매니저는

  • Node.js 런타임(실행환경)에서 돌아가며
  • 일반적으로는 패키지는 프로젝트의 node_modules 디렉토리에 저장된다.
  • package-lock.json에 패키지들의 정확한 버전정보를 추적
  • node_modules에는 package.json에 있는 라이브러리가 저장된다.

 

 

npm (Node Package Manager)

Node.js의 표준 패키지 매니저

Node.js를 설치하면 무조건 딸려오는 기본 패키지 매니저다. 

(별도 설치 필요없음)

셰계 최대 규모 패키지 보유

 

단점

- 여러개의 패키지 설치할 때 순차적으로 처리하기 때문에 속도와 성능이 안좋다.

- 패키지가 많아짐에 따라 빌드 성능이 떨어진다.

- 버저닝 이슈가 있다 

  •        package.json에 있는 패키지 버전이 ^,~ 등으로 범위로 지정되어 있는 경우가 많음
  •       개발자가 install하는 시점에 따라서 다른 버전 패키지가 설치될 수 있다.
  •       package-lock.json 파일을 통해 npm 최신 버전이 아닌 lock 파일에 있는 버전으로 설치가 가능하며
  •       package-lock.json 파일로 일정부분 보완이 가능하다

 

 

npx (Node Package Runner)

npm에서 제공해주는 하나의 도구

패키지의 최신버전 파일을 불러와 설치하여 실행시키고 실행된 이후 해당 패키지를 제거하는 방식

모듈이 많아 업데이트가 잦은 create-react-app 의 경우 npx를 설치하는 것을 권장한다. 

 

npx상세

의존성 라이브러리들을이 전역이나 로컬에 설치된 채 관리되면 로컬과 전역의 패키지관리가 굉장히 번거롭기 때문에 npx는 이를 해결하기 위한 도구로서 등장합니다.

npx는 기존에 npm 설치 방법과는 다르게 일일이 설치, 제거할 필요 없이 일회성으로 원하는 패키지를 npm 레지스트리에 접근해서 실행시키고 설치하는 실행도구입니다. 

 

즉 npx의 동작은 다음과 같다.

  1. 실행하고자 하는 패키지가 현재 실행 경로에 존재하는지 파악
  2. 존재한다면 패키지 실행
  3. 존재하지 않는다면 패키지의 최신 버전을 설치하고 실행해준 뒤 자동으로 삭제

 

 

yarn (Yet Another Resource Negotiator) (yarn 1.0)

npm의 단점 보완을 위해 Facebook에서 만든 js 패키지 매니저

 

npm의 단점?

1. 성능 및 설치 속도(순차적 설치)

→ yarn은 다운 받은 패키지 데이터를 캐시에 저장하여 중복된 데이터는 다운로드 하지 않는다.

→ yarn은 병렬적으로 설치한다.

 

2. 보안성 취약 (잠금 파일x, 패키지 설치 시 자동으로 포함된 의존성 패키지가 설치되도록 함)

→ yarn.lock으로 모든 디바이스에 같은 패키지를 설치하는 것을 보장하여 버전 차이로 인해 생기는 버그 방지

 

※그러나 npm역시 몇년간 발전을 거듭하며 단점을 보완했기 때문에 현재는 속도차이가 크게 나지 않고 npm도 package-lock.json이라는 잠금 파일을 제공한다.

 

yarn의 추가적인 기능 → workspace (npm도 v7부터 제공)

Workspace는 하나의 레포에서 여러 개의 프로젝트를 관리할 때 (모노레포) Workspace를 나누어 패키지 관리를 할 수 있는 기능 

 

ex) 클라이언트와 서버를 하나의 레포에서 모두 관리할 때, workspace 기능을 통해 yarn client startyarn server add {package}와 같이 각각 사용할 수 있다.
또, 각 프로젝트에서 중복되어 설치되는 패키지가 있는 경우 각각 추가되는 것이 아니라 root 경로에 호이스팅 되어 추가된다.

 

 

의존성 관리

각 패키지들은 의존성 관리를 어떤 방식으로 할까?

 

npm ~v2

같은 모듈을 의존할 때 각각 폴더 구조를 만들어서 사용하는 방식 

→ 중복이 많아져서 비효율적임

 

npm v3~, yarn

호이스팅 기법 사용

중복되는 것을 호이스팅해서 flat하게 만들어 사용

위 사진 B(1.0)과 B(2.0)처럼 버전 충돌이 날 수 있는 경우 나머지 B는 nested하게 호이스팅하지 않고 상위 모듈 아래에 둠

유령 의존성 발생

※유령 의존성(phantom dependency) : 중복 라이브러리의 위치 때문에 발생하는 현상.

유령 의존성은 호이스팅 방식을 사용하면서 package.json에 명시하지 않은 라이브러리를 사용할 수 있는 것이다. 이 라이브러리는 버전이 명확하지 않기 때문에, 다른 사용자에게는 버전 호환 실패로 인한 오류를 발생시킬 수 있다.

 

 

yarn Berry (yarn 2.0)

 - Facebook에서 발표한 yarn의 두 번째 버전 (2020)

 - Plug'n'Play(PnP) 라고 불리는 새로운 패키지 관리 방식
→ 유령 의존성에 관한 문제 해결

 

Plug'n'Play(PnP)

패키지를 프로젝트의 node_modules 디렉토리에 저장하지 않는다.

패키지들에 대한 의존성 정보는 .zip파일로 압축되어 .yarn/cache 폴더에 저장하고, 이를 찾기위한 정보를 .pnp.cjs 파일에 기록

 

 .pnp.cjs

.pnp.cjs 를 이용함으로써 별도의 디스크I/O 작업 없이도 패키지의 위치를 정확히 알 수 있기 때문에 시간도 단축되고, 중복설치를 방지하며, node_modules를 만들고 패키지들을 호이스팅시킬 필요가 없다.

/* react 패키지 중에서 */
["react", [
  /* npm:17.0.1 버전은 */
  ["npm:17.0.1", {
    /* 이 위치에 있고 */
    "packageLocation": "./.yarn/cache/react-npm-17.0.1-98658812fc-a76d86ec97.zip/node_modules/react/",
    /* 이 의존성들을 참조한다. */
    "packageDependencies": [
      ["loose-envify", "npm:1.4.0"],
      ["object-assign", "npm:4.1.1"]
    ],
  }]
]],

+ 현재 npm, pnpm에서도 이 방식을 제공하는 중

 

장점 

무거웠던 node_modules를 제거하고 옮긴 덕분에 의존성까지 github에 올릴 수 있다.

 - zero-install : git clone 이후 별도의 설치 필요없이 바로 소스코드를 실행할 수 있다 (yarn install 명령어 없이 바로 yarn start)

 - 브랜치 변경시에도 해당 브랜치에 이미 필요한 의존성 패키지가 존재하므로 yarn install 없이 실행가능

 - CI에서 의존성 설치하는 시간을 크게 절약한다 (토스에선 신입개발자의 환경세팅에 대해 이부분을 높게 평가하는 듯 하다)

 

각 패키지가 zip 아카이브로 압축되어 있으므로, 스토리지 용량을 크게 아낄 수 있다.

의존성을 구성하는 파일의 수가 많지 않으므로 변경 사항을 감지하거나 전체 의존성을 삭제하는 작업이 빠르다.

 

(추후에 yarn berry를 설치하고 초기세팅을 해볼 예정)

 

 

pnpm (performant npm)

yarn과 npm의 비효율을 개선한 노드 패키지 매니저 (2017)

pnpm은 패키지를 설치할 때 직접적으로 설치하는 방법 대신 심링크(하드링크)를 사용한다.

 

pnpm 사용이유

동작방식

npm으로 여러 프로젝트를 관리하다 보면 여러 프로젝트에서 같은 의존성을 사용하는 경우가 있는데

lodash를 사용하는 패키지 100개가 있다고 가정하였을 때 npm, yarn은 각 폴더별로 lodash 패키지가 100개가 복사된다.

반면에 pnpm은 lodash를 단 한번만 설치하고 다른 100개의 프로젝트에는 심링크로 연결하여 용량 측면에서 효율적으로 패키지를 관리한다. 

[모든 프로젝트에 대해 공유되는 의존성을 설치하고 링크하는 방식으로 동작]

 

content-addressable storage

전통적인 방식으로 데이터를 저장할 때는 데이터를 저장할 주소를 미리 정해놓고, 그 주소에 데이터를 저장하는데, CAS는 데이터의 내용(content) 자체가 주소(address)가 되는 방식

즉, 데이터의 내용을 해싱하여 그 결과를 주소로 사용하는데, 그렇기 떄문에 데이터를 찾는 것이 매우 빠르고 쉽다

 

pnpm 장점

  • 불필요한 I/O 과정을 없애 빠르고 효율적이다.
  • 패키지 중복 설치를 하지 않음으로써 사용 용량이 적다.
  • npm과 사용법이 비슷하다.
  • (모노레포 사용시) package.json에 peer dependency를 명시하지 않으면 사용할 수 없는 pnpm의 엄격함이 있다.
    ⇒ 모노레포에 익숙하지 않은 사람이 만들어내는 실수를 방지

 

 

 

 

Reference

'Front-End' 카테고리의 다른 글

Next.js톺아보기 What How When Why  (10) 2023.11.29
cookie  (0) 2023.11.15
IE에서 ajax cache이슈  (0) 2022.05.11
Comments