패키지 매니저란?
- 패키지를 다루는 작업을 편리하고 안전하게 수행하기 위해 사용되는 도구
- 패키지들을 쉽게 설치, 업데이트, 삭제, 설정할 수 있음
- 버저닝 관리
- npm, yarn, pnpm, pnp 등
{
"dependencies": {
"react": "^18.2.0" // react는 ≥ 18.2.0, <19 사이의 어떤 버전이든지 쓸 수 있다고 명시
}
}
일반적으로 프로젝트에서 필요한 의존성 패키지들의 정확한 버전정보는 package.json에 저장한다.
이렇게 명시한 정보를 바탕으로, 패키지 매니저는 모든 소스 코드 파일이 특정 버전의 라이브러리를 사용할 수 있도록 보장한다.
예를들어 npm install을 하면 해당 의존성의 명시된 버전을 설치하게 된다.
즉 패키지 매니저는 의존성의 버저닝 문제를 해결한다.
패키지와 라이브러리의 차이
자료를 찾아보다 패키지, 라이브러리 용어가 혼용돼서 사용되는데, 이 둘의 차이가 궁금해서 넣어봤다.
패키지와 라이브러리는 비슷한 용도로 사용되곤 하지만 엄밀히 따졌을 땐 다르다.
패키지
- 여러 개의 모듈(기능별 코드 파일)이나 라이브러리, 리소스, 문서 등을 하나로 묶어 배포 가능한 단위로 만든 것
- 보통 특정 기능을 제공하기 위해 관련된 파일들을 폴더 단위로 묶어놓은 형태
라이브러리
- 특정 기능을 수행하기 위한 코드 집합
- 여러 패키지, 모듈, 리소스 등을 포함할 수 있음
- 패키지보단 좀 더 넓은 개념
요약하자면
패키지는 배포와 설치의 단위이고, 그 안에 여러 라이브러리와 모듈이 포함될 수 있다.
예를 들어 "수학 라이브러리"라는 큰 기능 집합이 있고, 이것을 npm에 올릴 때 여러 모듈(덧셈, 뺄셈, 곱셈 등)을 하나로 묶어서 "math-utils"라는 패키지로 배포할 수 있다.
패키지 매니저가 동작하는 세 단계
Resolution, Fetch, Link 세 단계로 동작한다.
각각의 단계를 알아보자.
Resolution
package.json에 명시된 버전 범위에 따라 의존성들의 정확한 버전을 고정하는 단계라고 할 수 있다.
그리고 설치한 의존성들이 또 어떤 의존성을 가지는 지 확인하고, 이 의존성의 의존성들 역시 정확한 버전을 고정한다.
정리하면, Resolution 단계는 모든 기기에서 고정된 버전을 사용할 수 있도록 한다.
의존성 버전을 전부 고정시키고, 의존성의 의존성을 다 찾아서 그 버전도 고정시키며, 결과물을 yarn.lock이나 package-lock.json에 저장한다.
Fetch
Resolution의 결과로 결정된 버전을 실제로 다운로드하는 과정이다.
패키지 매니저는 이 과정에서 네트워크를 통해 필요한 파일들을 받아온다.
Link
Resolution/Fetch 된 라이브러리를 소스 코드에서 사용할 수 있도록 연결하는 과정이다.
npm의 사례를 알아보자.
<npm Linker>
node_modules기반의 npm Linker는 package.json에 명시하는 모든 의존성을 node_modules 밑에 하나하나씩 쓴다.
my-service/
└─ node_modules/
| ├─ react/
| |
| └─ @tossteam/tds-mobile/
| └─ node_modules/
| └─ @radix-ui/react-dialog
|
└─ src
└─ index.ts
문제점
- 비효율적인 의존성 탐색
module을 require할 때 현재 디렉토리부터 상위 디렉토리까지 일일히 다 탐색한다.
예를 들어
1. /home/user/project/src/components/node_modules/lodash 폴더를 찾는다. 없으면
2. /home/user/project/src/node_modules/lodash를 찾는다. 없으면
3. /home/user/project/node_modules/lodash를 찾는다. 여기 있으면 이걸 사용한다.
이런식으로 매번 모듈을 찾을 때마다 여러 디렉토리를 순차적으로 접근해야 하므로, 디스크에서 폴더와 파일을 반복적으로 확인하게 된다. 이 과정에서 많은 파일 입출력(I/O)가 발생해, 성능 저하의 원인이 될 수 있다. - 느린 설치 속도
npm은 이렇게 Link된 의존성들을 순차적으로 하나씩 복사해서 설치한다. 이로인해 설치 시간이 길어진다. - node_modules 용량 문제
이렇게 모든 의존성 패키지를 실제 파일로 복사해 저장하기 때문에 node_modules 폴더가 매우 커진다.
이런 npm의 문제를 하드링크, 심볼릭링크를 통해 해결한 것이 pnpm이다.
추후 추가 예정