Package Manager
: 패키지 매니저는 패키지를 설치, 업데이트, 수정, 삭제하는 작업을 편리하고 안전하게 수행하기 위해 사용되는 툴입니다.
패키지는 코드의 배포를 위해 사용되는 코드의 묶음으로 다음 3가지 정보를 가지고 있는 코드의 배포 단위입니다.
- 컴파일한 소프트웨어의 binary
- 환경 설정 configuration에 관련된 정보
- 의존 dependency 에 관련된 정보
JavaScript의 package manager로는 대표적으로 npm, pnpm, yarn이 있습니다.
Yarn Plug'n'Play는 Yarn의 최신 releases의 기본 설치 전략입니다.
기존의 node_modules 설치 또는 pnpm 스타일의 symlink-based 기반 방식등으로 대체할 수도 있지만,
많은 개선 사항으로 새프로젝트를 만들 때에는 PnP방식을 권장합니다.
PnP의 동작 방식
PnP는 node_modules 폴더 없이 동작합니다.
node_modules 대신 Node.js loader 파일(.pnp.cjs)을 생성하도록 Yarn에 지시합니다.
이 loader파일 에는 프로젝트의 dependency tree에 대한 모든 정보가 포함되어 있으며,
디스크에 있는 패키지의 위치를 도구에 알려주고, require 및 import 호출을 해결하는 방법을 알려줍니다.
PnP의 장점
- 설치 공간 최소화
Yarn PnP의 설치는 Node.js loader파일 pnp.cjs를 생성하는 한가지 작업을 수행합니다.
다른 package manager의 경우 많은 시간을 npm의 disk 또는 pnpm의 symlinks, hardlinks를 통해 한 위치에서 다른 위치로 파일을 복사하는 I/O 작업을 수행하는데 소비합니다.
symlink (Symbolic Link) = soft link
심링크 또는 심볼릭 링크는 리눅스 파일의 한 종류로, 컴퓨터의 다른 파일이나 폴더를 가리킵니다.
(윈도우 운영체제의 '바로가기'와 유사합니다.)
원본 파일 이름에 대한 pointer (참조) 역할을 하므로, 원본 파일이 삭제되거나 이동할 경우 소프트링크는 더이상 존재하지 않는 파일을 가리키게 되어 동작하지 않게 됩니다.
원본 파일/데렉터리와 다른 inode 번호를 가집니다.
hardlink
선택한 파일의 사본역할을 합니다.
원본파일이 삭제되더라도 하드링크에는 여전히 해당 파일의 데이터가 포함되어 있어서 데이터에 엑세스 할 수 있습니다.
원본 파일과 동일한 inode 번호를 가집니다.
(Inode 번호 : Index node number로 리눅스/유닉스 시스템에서 모든 파일을에 할당되는 고유 번호)
2. 디스크 간 공유 install
1의 장점과 연관되어 PnP을 사용하면 디스크의 모든 프로젝트에서 동일한 package artifacts를 재사용 할 수 있습니다.
각 package의 각 파일을 최종 대상에 hardlink해야하는 content-addressalbe store를 사용하는 pnpm과 달리
PnP loader는 cache 경로를 통해 package를 직접 참조하므로 많은 복잡성이 제거됩니다.
[ Zero install ]
; PnP는 .pnp.cjs 파일을 사용해 의존성 위치를 관리하는 것이라면,
zero-install은 프로젝트의 의존성과 결과물을 git에 포함하여 설치과정 없이 바로 사용하는 방식이다.
npm, PnP 방식 모두 사용가능하지만 PnP 방식만이 경제적이다.
모든 의존성과 환경을 버전관리하므로 일관성있는 개발환경을 제공하며, 초기설정 없이 빠른시작이 가능하지만,
의존성 업데이트시 추가적인 관리가 필요하고, 저장소의 용량이 증가할 수 있다는 단점이있다.
[ link에 대해 자세히 알아보기 ]
패키지 매니저는 3단계로 동작합니다.
- Resolution 단계
모든 기기에서 고정된 버전을 사용할 수 있도록 하는 단계입니다.
의존성 버전을 모두 고정시키고, 의존성의 의존성을 다 찾아서 그 버전도 고정시켜 결과물을 yarn.lock이나 package-lock.json에 저장합니다. - Fetch 단계
Resoulution으로 결정된 버전을 실제로 다운로드하는 과정입니다.
yarn.lock에 명시된 패키지를 패키지 매니저가 네트워크를 통해 필요한 파일들을 가져옵니다. - Link 단계
Fetch까지 된 라이브러리를 소스코드에서 사용할 수 있도록 환경을 제공하는 과정입니다.
1) npm Linker
package.json에서 명시하는 모든 의존성을 node_modules 디렉토리 밑에다가 하나하나씩 쓰는 역할
패키지를 찾으려면 node_modules를 계속 타고 올라가야하는 단점이 있음
2) pnpm Linker
기존의 node_modules 디렉토리를 그대로 사용하지만, 보다 빠르고 용량을 최적화하는 hard link 방식을 사용
npm 처럼 단순 복붙이 아니라, alias 거는 것 처럼 바로 접근할 수 있도록 하여 의존성을 디스크에 하나만 설치
3) PnP Linker
node_modules 디렉토리가 아닌 JavaScript 객체로 처리
.pnp.cjs 라는 파일에 의존성을 찾는 방법을 아래처럼 명시하여 JavaScript Map으로 관리
["@types/react", [\
["npm:19.0.1", {\
// yarn/berry/cache~~~ 에서
"packageLocation": "../../.yarn/berry/cache~~~"
"packageDependencies": [\
// types/react를 import하면 19.0.1 버전을 제공
["@types/react", "npm:19.0.1"],\
],\
}]\
]],\
Yarn 을 실행하면 Node.js 프로세스가 이 PnP Map을 메모리에 전부 로드하고 import, require 문에서 이 Map을 참조
node_modules를 순회할 필요없이 Map 연산만 하면되기 때문에 설치속도도 빠르고 import, require하는 속도도 빠름
[참고]
https://yarnpkg.com/features/pnp
https://toss.tech/article/lightning-talks-package-manager
'Study > Memo' 카테고리의 다른 글
Tailwind CSS 활용 - Clxs (0) | 2025.01.29 |
---|---|
Supabase으로 실시간 채팅기능 만들기 (Real-time database) (1) | 2024.11.19 |
[React] useOptimistic hook (0) | 2024.11.18 |