패키지 매니저의 진화

JavaScript 패키지 매니저

버전 문제를 해결해서 외부 의존성을 올바르게 참조할 수 있도록 도와주는 프로그램입니다. 코드에서는 절대/상대 경로로 import, require만 하고 있는데 버전별로 동작이나 구현이 다르기 때문에 package.json에 버전을 명시합니다.

패키지 매니저의 동작

  • Resolution

    • 라이브러리 버전 고정

      react: "^18.1.0" // 18.1.0 <= version < 19.x.x 사이의 최신버전
    • 라이브러리의 다른 의존성 확인

    • 라이브러리의 다른 의존성 버전 고정

      • 모든 기기에서 고정된 버전을 사용하게 하고 결과물을 yarn.lock, package-lock.json에 저장합니다.

  • Fetch

    • 선택된 버전의 파일을 다운로드(일반적으로 npm registry)

  • Link

    • Resolution/Fetch된 라이브러리를 소스 코드에서 사용할 수 있는 환경 제공

    • npm Linker

      • node_modules 디렉토리에 package.json에 명시하는 의존성을 순서대로 쓰는 동작

    • pnpm Linker

      • npm linker의 중복되는 의존성으로 인한 디스크 용량 문제를 해결한 개선된 npm

      • alias를 사용하는 Hard link 방식을 사용하여 개선하여 디스크문제와 속도 개선

    • PnP(Plug`n Play) Linker

      • node_modules를 벗어나고 싶다는 생각으로 접근한 것

      • import할 때 어떤 파일에서 import하고 무엇을 import하는지 접근

        • node_module가 아니라 .pnp.cjs라는 파일에서 객체(JavaScript Map)로 처리(특정 디렉토리에서 react를 import하면 18.1.0을 제공하는 방식)

        • yarn.lock기반으로 .pnp.cjs 만들면 됩니다.

Node.js와 함께 기본적으로 설치되기 때문에 대표적이고 가장 점유율이 높다.

  • 해결하고자 한 문제

    • 외부 의존성의 버전 문제를 해결

  • 한계

    • 패키지들을 각각 별도로 설치하기 때문에 공유된 의존성이 중복으로 설치되고 디스크 공간을 많이 차지 할 수 있다.

    • 의존성 트리가 깊어지면 설치 속도가 느려질 수 있다.

  • 해결하고자 한 문제

    • alias를 이용한 Hard Link를 이용해서 중복설치를 피하여 npm의 의존성 문제(디스크 공간, 속도)를 해결

      • 글로벌 저장소 → node_modules/.pnpm으로 하드링크

      • node_modules/.pnpm → node_modules으로 심볼릭링크

    • yarn과 npm의 공통적인 문제인 유령 의존성(직접 설치하지 않았는데 import 되는 것) 해결

    • 로컬 디렉토리에 캐싱된 의존성이 있다면 symbolic link를 거는 방식을 이용해서 새로운 프로젝트에서도 빠른 속도

  • 한계

    • zero install은 불가능합니다

    • Docker image에 pnpm 설치 필요(기본 제공 x)

  • 해결하고자 한 문제

    • 여러 패키지를 병렬로 설치할 수 있어서 npm보다 빠른 속도를 보장합니다.

  • 한계

    • npm과 같은 호이스팅 문제(유령 의존성)

    • 디스크 공간 중복 사용

    • 복잡한 의존성 트리에서 느린 속도

Yarn의 새로운 버전으로 PnP, Zero-install을 지원합니다.

  • 해결하고자 한 문제

    • PnP를 이용하여 node_modules를 벗어나 .pnp.cjs로 빠른 속도

  • 한계

    • PnP 모드에서 일부 도구 호환성 문제(IDE 확장 프로그램 설치)

    • Zero-install 사용 시 .yarn/cache 폴더(내부에 zip파일)가 Git에 포함되어 저장소 크기 증가

  • Corepack이 등장한 배경

    • Node.js 14+에서 제공

    • 프로젝트마다 다른 패키지 매니저 사용 (npm, yarn, pnpm)

    • CI/CD과 팀원들의 로컬에서 패키지 매니저 버전 불일치로 인한 문제

  • Package Manager 버전 관리

    • package.jsonpackageManager 필드로 버전 명시

    • Corepack 활성화(corepack enable) 후 패키지 설치 시 packageManager 기준으로 버전 관리

성능 비교

실무 팁

마이그레이션 고려사항

  • npm → yarn classic

    • package-lock.json, node_modules 삭제 후 yarn.lock 생성

    • npm scripts는 그대로 사용 가능

    • 호이스팅 차이로 인한 문제 체크

      yarn audit
      npm ls --depth=0
  • npm → pnpm

    • 유령 의존성 문제로 인한 에러 발생 가능

      • 코드에서 없는 의존성인데 사용하는 케이스 존재할 수 있어서 pnpm에서는 package.json에 누락된 의존성 추가 필요

    • package-lock.json, node_modules 삭제 후 pnpm-lock.json 생성

    • 스크립트 차이 (npm run vs pnpm run)

  • yarn classic → yarn berry

    • yarn set version berry (version 변경)

    • yarn config set nodeLinker pnp(pnp 활성화해도되고 node_modules로 써도됩니다)

    • .yarnrc.yml (Yarn Berry(v2+)의 설정 파일)파일 생성

    • PnP 모드에서 IDE 설정 필요

  • yarn classic → pnpm

    • 코드에서 없는 의존성인데 사용하는 케이스 존재할 수 있어서 pnpm에서는 package.json에 누락된 의존성 추가 필요

    • 스크립트 실행 방식 차이 (yarn run vs pnpm run)

npm ci vs npm install

  • npm ci

    • 프로덕션/CI 환경에서 주로 사용

    • package-lock.json만 참조 (수정 없이 명시된 버전 설치)

  • npm install

    • 개발 환경에서 주로 사용

    • package.jsonpackage-lock.json 모두 참조

    • 버전 범위 내에서 최신 버전 설치 가능

    • package-lock.json 업데이트 가능

peer dependencies 문제

  • npm@7부터는 peerDependencies가 기본으로 설치되고 버전이 맞지 않으면 에러

    • npm@3 ~ npm@6과 yarn에서는 warning

    • --legacy-peer-deps: conflict에 대한 warning이 발생해도 일단 설치

    • --strict-peer-deps: strict하게 검사

    • 추가 옵션의 경우 .npmrc를 통해 설정 가능합니다.

JavaScript 표준으로 패키지를 관리

package.json가 없는 환경에서는 Import Map를 사용해서 패키지 매니저 없이 가져올 수 있습니다.

<script type="importmap">
{
  "imports": {
    "react": "<https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js>"
  }
}
</script>
<script type="module">
  import React from 'react';
</script>

PnP vs. Zero-install

  • PnP(Plug and Play)는 Javascript Map 객체를 활용해 의존성을 관리하는 방식

  • Zero-install

    • PnP의 Javascript Map 객체와 Fetch된 의존성들까지 Git에 넣어서 관리하는 방식

    • npm의 node_modules를 Git에 넣어서 관리하는 방식

유용한 도구

Reference

Last updated