프론트엔드 개발자의 기록 공간

[FE_Roadmap] Package Managers 본문

개발지식

[FE_Roadmap] Package Managers

[리우] 2023. 12. 9. 23:42

Package Managers

  • 컴퓨터의 운영 체제를 위해 일정한 방식으로 컴퓨터 프로그램의 설치, 업그레이드, 구성, 제거 과정을 자동화하는 소프트웨어 도구들의 모임이다.

npm

  • npm(node package manager)은 자바스크립트 패키지 매니저입니다. Node.js에서 사용할 수 있는 모듈들을 패키지화하여 모아둔 저장소 역할과 패키지 설치 및 관리를 위한 CLI(Command line interface)를 제공합니다. Node.js 생태계의 앱스토어나 플레이스토어 같은 역할을 합니다.
  • npm 레지스트리에는 640,000개가 넘는 패키지가 포함되어 있으며, 패키지는 의존성(dependencies) 및 버전을 추적할 수 있도록 구성됩니다.

package.json

  • package.json은 프로젝트 정보와 의존성(dependencies)을 관리하는 문서입니다.
    이미 작성된 package.json 문서는 어느 곳에서도 동일한 개발 환경을 구축할 수 있게 해줍니다.

package-lock.json

  • package.json이 동일한 개발 환경 구축을 위한 정보를 가지고 있지만, 다양한 경우에 의해 동일한 개발 환경 구축에 문제가 발생할 수 있습니다.
  • 상위 모듈에서 사용하는 하위 모듈 중 일부가 버전이 변경될 경우 결과가 다르게 나타날 수 도 있습니다.
  • 이를 방지하기 위해 npm으로 node_modules의 구성 트리 또는 package.json을 수정하는 모든 작업에 대해 package-lock.json이 자동으로 생성됩니다.
    모든 작업에 대해 자동 생성하므로 의존성 업데이트와 같은 버전 변경에 대해서도 동일한 모듈 트리를 생성할 수 있게 됩니다.

최종적으로 위의 정보를 기준으로 로컬 폴더 node_modules 폴더에 설치가 된다.

 

단점

  • 일관적이지 않은 패키지 버전
    • 시멘틱 버저닝으로 인한 버전 문제 
    • 시멘틱 버저닝이란 간단히 말해 1.2.3 처럼 버전을 세 가지 숫자가 들어갈 수 있는 자리로 구분하고, 각각의 자리에 현재 버전이 이전 버전과 어떤 관계가 있는지 암시하도록 하는 방법입니다. 예를들어 eslint": "^8.27.0 모듈을 설치할 경우 가장 앞 숫자인 가장 앞 숫자인 메이저 버전을 제외한 두 자리 (마이너, 패치) 버전까지는 변경을 허용할 수 있다는 의미입니다. 메이저 버전인 8이 변경되지 않는 범위에서는 8.17.10 버전이나, 8.18.0 버전 등이 모두 사용될 수 있습니다.
  • 순차적인 설치로 인한 속도 문제

Yarn v1

  • 위의 문제를 해결하기 위해 Facebook에서 만든 Yarn(Yet Another Resource Negotiator)은 자바스크립트 패키지 매니저가 나왔습니다.
  • yarn.lock 파일을 통해 패키지 버전 잠금을 지원하여 프로젝트에서 의존하는 모든 패키지를 어느 환경에서든 항상 동일한 버전으로 설치할 수 있게 만들어줬습니다.
  • 동시에 여러 패키지를 설치를 통해 속도가 개선되었습니다.

현재 npm & Yarn v1

  • 현재는 서로 비슷한 수준의 속도와 npm에서도 shrinkwrap 옵션등을 통해 서로 비슷한 수준입니다.
  • node_modules 기반으로 매우 큰 공간을 차지합니다. 간단한 프로젝트도 수백 메가바이트의 node_modules 폴더가 필요합니다. 또한 많은 I/O 작업이 필요합니다.

  • NPM 및 Yarn v1에서는 중복해서 설치되는 node_modules를 아끼기 위해 끌어올리기(Hoisting) 기법을 사용합니다. 이 때문에 유령 의존성 문제가 발생합니다.

Yarn Berry

  • Yarn Berry는 Node.js를 위한 새로운 패키지 관리 시스템으로 2020년 1월 25일부터 정식 버전(v2)가 출시되어, 현재는 Babel과 같은 큰 오픈소스 레포지토리에서도 채택하고 있습니다.
  • Yarn Berry는 기존의 “깨져 있는” NPM 패키지 관리 시스템을 혁신적으로 개선합니다.
  • Yarn Berry는 node_modules를 생성하지 않습니다. 대신 .yarn/cache 폴더에 의존성의 정보가 저장되고, .pnp.cjs 파일에 의존성을 찾을 수 있는 정보가 기록됩니다. .pnp.cjs를 이용하면 디스크 I/O 없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 각 라이브러리는 어디에 위치하는지를 바로 알 수 있습니다. (Plug’n’Play (PnP))
/* 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"]
    ],
  }]
]],
  • Yarn PnP 시스템에서 각 의존성은 Zip 아카이브로 관리됩니다.
    • node_modules 디렉토리 구조를 생성할 필요가 없기 때문에 설치가 빠르다.
    • 패키지는 버전마다 하나의 Zip 아카이브만을 가지기 때문에 중복해서 설치되지 않습니다.
  • Yarn PnP은 의존성을 압축 파일로 관리하기 의존성을 Git으로 관리하여 사용한다면 zero install의 장점을 누릴 수 있습니다.

이렇게 Yarn Berry에서 의존성을 버전 관리에 포함하는 것을 Zero-Install이라고 합니다.

토스팀 이렇게 Yarn Berry를 도입함으로써 JavaScript 의존성을 효율적이고 안전하게 다룰 수 있었습니다. 오래 걸리던 CI 속도를 60초 이상 단축하기도 했습니다.

pnpm

  • pnpm은 2017년에 만들어졌으며, npm의 설정을 바꿀 필요 없이 바로 사용가능하며, 속도와 안정성 등 다양한 기능 향상이 이루어지는 대체품으로, npm만 있다면 바로 사용할 수 있습니다.
  • npm 또는 Yarn 클래식을 통해 의존성을 설치할 때, 모든 패키지는 모듈 디렉토리의 루트로 호이스트됩니다. 결과적으로, 소스 코드는 프로젝트에 의존성으로 추가되지 않은 의존성에 접근할 수 있습니다.

npm & yarn v1 유령 의존성

pnpm은 symlink를 사용하여 프로젝트의 직접적인 의존성만을 모듈 디렉토리의 루트로 추가합니다.

pnpm은 이러한 호이스트 방식 대신, 다른 dependencies를 해결하는 전략인 content-addressable storage를 사용했습니다. 따라서 모든 버전의 dependencies은 해당 폴더에 물리적으로 한번만 저장되므로, single source of truth를 구성하고, 상당한 디스크 공간을 절약할 수 있습니다.


참고

728x90
Comments