ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • npm, yarn, pnpm, 뭘 써야할지 모르겠다면?
    일찍 알았으면 좋았을 넓고 얕은 개발 지식 2025. 1. 5. 23:08

    멘토링중에 이런 질문이 있었습니다. 코드 검색하다 보면 pnpm이라는 게 종종 보이는데, pnpm에 대해 궁금하다고 하셨어요.

    마침, 저도 yarn, npm은 거리낌 없이 쓰던차에 왜 npm을 쓰고, 왜 yarn을 썼는지 이유 없이 그냥 썼습니다. 마치 어렸을 적 스타크래프트 치트키 외워서 쓰듯이 (에스 에이치 오 더블유 엠 이...) npm install, yarn add 이렇게 몸의 기억으로 썼습니다. 그래서 pnpm을 알아보면서 패키지 매니저 종류는 뭐가 있고 장단점은 무엇인지, 언제 쓰면 좋을지 등등등 알아봤습니다.

     

    패키지 매니저

    패키니 매니저가 하는일은 프로젝트에 의존성을 설치, 삭제, 업데이트하는 일 이외에도 많습니다. pacakge.json 파일에서 dependencies와 devDependencies를 통해 프로젝트에 필요한 라이브러리 버전을 관리하고, 팀원들이 동일한 개발환경을 유지할 수 있도록 해줍니다. package.json에 scripts 섹션으로 자주 사용하는 명령어들을 정의하고 실행시킬 수도 있어요. npm start도 scripts에 정의되어 있어서 명령어로 사용할 수 있습니다.

    그리고 lock 파일로 모든 의존성의 정확한 버전을 기록하고, 보안 취약점을 검사할수도 있습니다. 특정 패키지 매니저는 워크스페이스 혹은 모노레포 환경을 구축해서 효율적인 제품 관리를 할 수 있게 해 줍니다.

    npm

    Node Package Manager로 알려진 npm은 사실 Node Pacakge Manager의 약자가 아닙니다. npm에서 npm을 검색해 보면, 

    a JavaScript package manager로 소개하고 있습니다. npm의 이름은 FAQ on Branding에 있는데 npm의 전신은 사실 다양한 플랫폼에 다양한 것을 설치하는 배시 함수인 "pkgmakeinst"의 줄임말인 "pm"이라는 이름의 배시 유틸리티였습니다.라고 소개하고 있어요.

     

    장점

    javascript 생태계의 기본이 되는 가장 오래된 패키지 매니저입니다. 거의 모든 javascript 라이브러리가 포함된 가장 큰 저장소이기도 합니다. 2010년에 공개된 npm은 대부분의 javascript 프로젝트가 지원하고, 대부분의 문제들이 해결되어 있고, 안정적인 패키지 매니저입니다. 

    단점

    다른 패키지 매니저들에 비해 상대적으로 설치 속도가 느립니다. 개발환경에서는 하나씩 하나씩 설치해서 큰 문제가 없지만, 배포환경에서 설치속도의 차이가 생깁니다. npm은 패키지 1,2,3이 있다면 1의 설치가 완료되어야 2의 설치가 시작되고, 마찬가지로 2가 완료되어야 3이 설치되는 직렬로 패키지를 설치합니다. 그래서 의존성이 많다면 설치 시간이 길어질 수 있습니다.

    하나의 프로젝트에 하위 프로젝트가 있다면, 각각의 프로젝트에 의존성도 각각 설치해야 합니다. 뭔가 당연한 이야기 같지만, 다른 패키지 매니저는 이런 설치를 줄이는 방법을 채택하고 있어서 상대적으로 디스크에 많은 용량을 차지하게 됩니다.

    ~/Projects/
      ├── project-a/
      │   ├── package.json
      │   └── node_modules/
      │       ├── react/
      │       ├── react-dom/
      │       └── lodash/
      │
      └── project-b/
          ├── package.json
          └── node_modules/
              ├── react/
              ├── react-dom/
              └── lodash/

     

    yarn

    Yarn은 Facebook이 개발한 JavaScript 패키지 매니저입니다. 2016년에 처음 공개된 Yarn은 Yarn이라는 이름은 Yet Another Resource Negotiator의 약자로, JavaScript 프로젝트의 의존성을 더 효율적으로 관리하겠다는 목표를 담고 있습니다.

     

    장점

    Yarn의 가장 큰 특징은 성능에 있습니다. 패키지 설치 시 병렬 처리 방식을 도입하여 npm의 직렬 설치 방식보다 훨씬 빠른 설치 속도를 제공합니다. 예를 들어 세 개의 패키지를 설치할 때, npm이 순차적으로 설치하는 것과 달리 Yarn은 동시에 설치를 진행합니다.

    또한 Yarn Berry(2.0 이상)에서 도입된 Plug'n'Play(PnP) 시스템은 node_modules 없이도 의존성을 관리할 수 있게 해 주었습니다. 더 나아가 Zero Install이라는 혁신적인 기능을 통해 의존성을 Git에 포함시켜, 새로운 개발 환경에서도 패키지 설치 없이 즉시 개발을 시작할 수 있게 되었습니다.

    단점

    하지만 Yarn에도 단점은 있습니다. npm에 비해 상대적으로 짧은 역사로 인해 안정성 면에서 우려가 있으며, PnP 시스템 사용 시 일부 도구나 라이브러리와 호환성 문제가 발생할 수 있습니다. 또한 npm보다 복잡한 설정과 높은 학습 곡선은 새로운 사용자들에게 진입 장벽이 될 수 있습니다. 커뮤니티 규모도 npm보다 작아 문제 해결을 위한 레퍼런스가 상대적으로 부족한 편입니다.

     

    yarn workspace

    yarn berry에서는 workspace라는 모노레포 환경으로 관리할 수 있습니다. npm은 하나의 프로젝트에 여러 개의 하위 프로젝트가 있을떄에도 각각 독립적인 node_modules를 가지고 있어 중복 설치와 버전 관리의 어려움이 있었지만, workspace는 하나의 node_modules로 여러 프로젝트의 의존성을 관리할 수 있게 되었습니다. 의존성 버전의 일관성을 유지할 수 있고, 공통 패키지도 실시간으로 반영할 수 있는 장점이 있습니다.

    //workspace 관리 전
    my-project/
      client/        # 각각 독립적인 node_modules
        node_modules/
        package.json
      server/        # 각각 독립적인 node_modules
        node_modules/
        package.json
      share/         # 공통 라이브러리
        node_modules/
        package.json
        
        
    //workspace 관리 후
    my-project/
      package.json   # workspace 설정
      node_modules/  # 공유 node_modules
      client/
        package.json
      server/
        package.json
      share/
        package.json

     

    pnpm

    pnpm(Performance NPM)은 2017년에 처음 공개된 JavaScript 패키지 매니저입니다. 기존 패키지 매니저들의 단점을 해결하기 위해 탄생했고, 특히 디스크 공간 활용과 의존성 관리 측면에서 강력합니다.

    장점

    pnpm은 모노레포 구성이 가능하고, 의존성 관리를 효율적으로 할 수 있습니다. pnpm은 컴퓨터에 직접. pnpm-store를 설치해 모든 패키지를 저장합니다. 프로젝트에서 특정 의존성이 사용되면 이 저장소와 연결된 심볼릭 링크로 참조해 동일한 패키지가 여러 프로젝트에서 사용되어도 디스크에는 한 번만 저장되어서 용량을 획기적으로 줄일 수 있고, 설치속도 또한 yarn처럼 병렬 설치를 지원해 빠르게 설치할 수 있습니다.

    pnpm은 유령의존성(phantom dependencies)이라고 하는 기존의 패키지매니저에서 나오던 문제를 해결했습니다. 예를 들어, @mui/material은 내부적으로 lodash를 의존하고 있습니다. 그래서 @mui/material만 설치해도 lodash도 사용이 가능합니다. 이 lodash가 유령 의존성입니다. 만약, mui팀이 lodash 의존성을 제거하거나, 버전을 변경하면, 참조하고 있던 프로젝트에 오류가 생기거나, 동작을 멈출 수도 있는 잠재적 위험이 있습니다. pnpm은 유령의존성의 사용을 엄격하게 제한하기 위해, pacakge.json에 명시되어있지 않은 패키지는 사용할 수 없도록 막습니다. 마치 typescript에서 특정 타입을 입력하지 않아 에러 처리하는 것처럼.

     

    단점

    npm이나 yarn에 비해 상대적으로 커뮤니티가 작아 문제 해결을 위한 레퍼런스가 부족할 수 있어요. 그리고 일부 패키지의 호환성 문제나 아직 pnpm을 지원하지 않는 패키지가 있기도 합니다.

     

    또한, 기존 프로젝트를 pnpm으로 마이그레이션 할 때 유령의존성 문제로 인한 어려움을 겪을 수도 있어요. pacakge.json에 명시적으로 적어야 하기 때문이죠.

     

    그래서 어떤 걸 어떻게 선택하면 좋을지?

    작은 규모의 프로젝트라면 npm, yarn 무엇을 선택해도 문제가 없을 것 같습니다.

    멀티 레포 구조로 충분히 관리가 가능하다면 npm, yarn(classic)으로 우선 관리하다가, 모노레포의 필요성을 느끼면 yarn Berry 혹은 pnpm을 고려해 봐도 좋을 것 같아요.

Designed by Tistory.