# 02. 패키지 매니저 (Package Manager)

## 용어 정리

1. 의존성 (dependency)
   1. 내 프로젝트에 사용되는 다른 사람이 개발한 패키지
2. 패키지 (package)
   1. third-party SW
   2. 이상적으로 단 하나의 문제만을 해결한다.
3. 번들 (bundle)
   1. software를 개발하기 위해 작성한 모든 JS코드 파일을 실행 가능한 하나의 파일로 만드는 것
4. 패키지 매니저 (package manager)
   1. 프로젝트의 의존성(=dependency=package)을 관리하는 시스템
5. 패키지 레지스트리 (package registry)
   1. 패키지와 관련된 메타데이터로 패키지를 설치하는데 필요한 구성을 저장하거나 패키지 버전을 추적한다.

## 의존성

1. 특징
   1. 웹 프로젝트는 의존성을 가질수도, 갖지 않을 수도 있다.
   2. 내가 의존하고 있는 SW도 의존하고 있는 다른 SW가 있을 수도 있다. (sub-dependency)
2. 종류
   1. React, Vue : entire JS library or framwork
   2. Human Readable date library: small utility
   3. prettier, or EsLint: command line tool
3. 주입 방법
   1. modern build tool이 없다면 html 문서에`<script>` 태그를 통해서 주입되겠지만
   2. 우리가 작성한 코드와 의존성을 합치기 위해서는 modern bulding tool이 필요하다.
   3. 만약 의존성이 새로운 버전을 출시한다면 업데이트 해주어야 할 수 있다.

## 패키지 매니저

1. 역할
   1. JS 파일 패키지를 인터넷에서 검색해서 찾는다
   2. 그 패키지 중에 알려진 취약성을 지닌게 없는지 확인한다
   3. 패키지를 다운로드하여 프로젝트 내부 폴더의 알맞은 경로에 저장한다
   4. 다운로드한 패키지를 개발중인 app에 포함하기 위한 코드를 작성한다.
   5. 위의 작업을 패키지가 가진 모든 sub-dependency에 해당하는 패키지들을 설치할 때에도 반복한다.
   6. 삭제하고자 할 때는 위에서 다운로드 받거나 생성했던 모든 파일을 제거한다.
   7. 의존성을 복제한다. (프론트엔드 개발에서 중요하고 일반적이어진 작업)
   8. 위의 작업들 즉, 직접 일일이 다운로드 받고, 설치하고, 저장하는 일련의 과정을 IDE 안의 터미널에서 해결할 수 있다.
2. 설치 위치에 따른 차이
   1. npm의 경우에 의존성을 어디에 설치할지에 대한 두가지 옵션이 있다.
   2. 의존성은 전역으로 혹은 지역적으로 설치될 수 있다.
   3. 전역으로 설치하는 것에 대한 좋은 점이 더 많음에도 불구하고, 지역적으로 ㅈ설치하는 것의 장점이 더 "중요"하다.
   4. 지역적으로 설치하는 것의 장점
      1. 한 프로젝트가 특정 실행에 대해 Webpack에 의존한다고 했을 때, 같은 프로젝트가 다른 기기에 설치되었거나 한참 시간이 지난 후에 다시 볼 때 실행 파일이 여전히 작동되어야한다.
      2. 만약 Webpack 의 새로운 버전이 설치되었다면, 그것이 compatible(양립할 수 있는, 충돌없이 서로 상호작용하면서 존재)하지 않을 수 있다.
      3. 이것을 옮기기 위해서 의존성들은 프로젝트에 지역적으로 설치되어야 합니다.
      4. 지역적 의존성이 진짜로 빛을 발하려면, 기존의 프로젝트를 다운로드 받고 실행시켜 보면 됩니다.
      5. 박스 바깥에서도(out of the box), 프로젝트가 작동하고 모든 의존성이 정상적으로 작동한다면, 로컬 종속성 덕분에 코드가 이동가능하다는 것입니다.
3. 패키지 레지스트리 (package registry)
   1. 개념
      1. 패키지와 관련된 메타데 이터
      2. 레지스트리는 패키지가 게시되고, 설치할 수 있는 중앙 장소이다.
      3. 패키지 관리자가 작동하려면 패키지를 설치할 장소를 알아야한다.
      4. 패키지를 설치할 장소에 대한 정보는 레지스트리의 형태로 제공된다.
         1. 패키지 관리자일 뿐만 아니라, JS 패키지에 일반적으로 사용되는 패키지 레지스트리의 이름이기도 하다.
         2. npm 레지스트리는 npmjs.com에 있다.
         3. npm 이 유일한 옵션이 아니고 다른 대안이 존재합니다.
      5. 직접 패키지 레지스트리를 관리하는 방법
         1. Microsoft Azure와 같은 제품을 사용하면 npm 레지스트리에 대한 프록시를 만들 수 있다.
         2. 특정 패키지를 재정의 하거나 잠글 수 있음
         3. github도 패키지 레지스트리를 제공
         4. 시간이 지남에 따라 더 많은 옵션이 나타날 가능성이 높다
   2. 역할
      1. 패키지를 설치하는데 필요한 구성을 저장
      2. 패키지 버전을 추적한다.
      3. 패키지를 업로드
      4. 클라이언트가 상호작용하는 루틴을 빌드하기 위한 api 세트, 설치 검색 업그레이드 확인 등이 포함된다.
      5. 사용자 액세스를 관리하고 현재 있는 모든 패키지를 볼 수 있는 관리자 대시보드 혹은 CLI (Command Line Interface Utility)
   3. 예시
      1. 대부분의 언어와 프레임워크는 패키지를 다운로드하여 사용할 수 있는 자체 공개 패키지 레지스트리를 제공한다.
      2. 이러한 저장소는 오픈 소스 커뮤니티 또는 컨소시엄에서 유지 관리하고 검증하므로 이와 관련된 최소 보안 표준이 있지만 보안을 최대한 중요시하는 조직에는 충분하지 않을 수 있다.
      3. Python의 PyPI 저장소, Debian의 APT 저장소, NodeJS NPM 등이 이러한 공개 레지스트리의 예다.

### NPM, Yarn, PNPM 비교하기

1. 개요
   1. 각각 JavaScript 프로젝트를 관리하는 데 고유한 이점과 단점이 있다. 차이점을 살펴보고 필요에 맞는 것을 찾아야한다.
2. NPM
   1. 특징
      1. JavaScript 생태계의 일부
      2. Node.js와 함께 번들로 제공됨
      3. 기본 패키지 관리자 역할
      4. 가장 널리 사용되는 패키지 매니저
      5. NPM은 캐싱 메커니즘을 사용하지 않으므로 매번 각 패키지를 다운로드하고 설치
   2. 장점
      1. 사용하기 쉬움
      2. 방대한 오픈 소스 JS 패키지와 라이브러리 저장소
      3. 개발자에게 포괄적인 리소스
      4. 종속성의 취약점을 확인하는 내장 보안 감사 도구가 있음
   3. 단점
      1. 느림
      2. flattened node\_modules 폴더를 사용한다.
      3. flat tree구조로 중첩된 node\_module 폴더 문제를 해결하려 했으나 동일한 의존성에 대해 다른 버전을 요구하는 패키지들이 있을 수 있으므로 충돌을 막기 위한 중첩된 패키지를 생성할 수 있음
3. Yarn
   1. 특징
      1. Facebook에서 만듦
      2. YARN도 패키지의 글로벌 캐시를 사용하지만 여전히 각 프로젝트에 복사
   2. 장점
      1. 속도와 안정성에서 NPM의 단점 중 일부를 해결하도록 설계됨
      2. flat-dependency structure를 사용해서 nesting이나 package 중복을 피할 수 있다.
      3. 로컬 캐시로부터 패키지의 오프라인 설치를 지원한다.
      4. 다양한 환경에서 일관되고 결정적인 패키지 버전을 보장하는 더 나은 해결 알고리즘이 있다.
   3. 단점
      1. flattened node\_modules 폴더를 사용한다.
      2. 일부 npm 패키지들과 호환성 이슈가 있을 수 잇음
      3. 아직 수정되거나 해결되지 않은 버그나 문제가 있을 수 있습니다.
4. PNPM
   1. 특징
      1. Performant Node Package Manager
      2. 2016년 Zoltan Kochan이 만듦
      3. symlinked node\_modules 라는 새로운 접근 방식을 사용함
         1. 이 접근 방식은 각 프로젝트에 패키지를 복사하는 대신 패키지의 글로벌 저장소에 하드 링크를 만듦
         2. pnpm은 패키지를 전역 pnpm store에 설치하고, 심볼링 링크와 하드 링크를 사용하여 의존성의 중첩 구조를 생성.
         3. 프로젝트의 의존성 트리와 똑같은 형태로 링크만 걸어주
      4. 하드링크란
         1. 파일 시스템 내에서 동일한 파일 내용을 가리키는 두 개 이상의 파일 이름
         2. 하나의 파일에 대해 두 개의 하드링크가 있을 때, 하나의 하드 링크를 삭제해도 원본 파일은 유지됨.
         3. 파일데이터는 모든 하드링크가 삭제 될때까지 파일 시스템에 유지됨.
         4. pnpm store에 저장된 패키지나, node/modules/.pnpm에 저장된 패키지나 동일한 파일을 참조 하고 있음
         5. 어디서나 동일한 용량을 표시하지만 결국에는 참조하는 단 하나의 파일만큼의 용량을 차지 합니다.
   2. 장점
      1. npm과 yarn의 대안으로, 더 효율적이고 신뢰할 수 있도록 설계됨
      2. Node.js를 위한 셋중에 가장 빠르고 디스크 공간 효율적인 패키지 관리자
      3. node\_modules 폴더에 복사하는 대신 글로벌 스토어에서 패키지를 연결하기 위해 하드 링크나 심볼릭 링크를 사용
      4. 패키지가 package.json 파일에 선언되지 않은 모듈에 액세스하는 것을 방지하는 엄격한 종속성 격리를 지원
      5. 종속성의 취약점을 확인하는 내장 보안 감사 도구가 있음
   3. 단점
      1. 일부 npm, yarn 패키지들과 호환성 이슈가 있을 수 잇음
      2. 아직 수정되거나 해결되지 않은 버그나 문제가 있을 수 있습니다.

         | Metric                         | NPM    | YARN   | PNPM  |
         | ------------------------------ | ------ | ------ | ----- |
         | Installation time (cold cache) | 67.4s  | 47.6s  | 32.3s |
         | Installation time (warm cache) | 9.1s   | 4.9s   | 4.4s  |
         | Disk space used                | 237 MB | 175 MB | 39 MB |
