1. Why?
삼성청년SW아카데미에서 첫 프로젝트인 공통 프로젝트를 시작했다.
본격적으로 개발을 하기 전에 우선 어떤 기술을 사용할지부터 결정해야 하는데, 팀원 중 Package Manager에 대한 지식이 있는 사람이 없기에 어떤 Package Manager를 사용할지 찾아보고 팀원들에게 공유하고자 한다.
1. Package Manager가 뭔데,, 어디 쓰는건데,,
1) 모듈? 패키지?
- 모듈 → js에서 require라는 node.js의 도구를 사용해서 가져올 수 있는 것
- 패키지 → 그런 모듈을 모아놓은 것
2 ) Package Manager란?
- Package Manager가 없다면?
- 사용하고 싶은 Package를 직접 다운로드 받아서 설치해야함
- 의존성 처리? 그건 알아서..
- 만약 사용하던 라이브러리가 업데이트 된다면?
- 알아서 릴리즈노트 비교해가면서 업데이트 + 직접 코드 다운로드 받아서 새로운 버전으로 교체,,
- 사용하고 싶은 Package를 직접 다운로드 받아서 설치해야함
- Package를 관리하기 위해서 등장한 게 Package Manager
- 프로젝트에 필요한 외부 라이브러리, 모듈, 플러그인을 설치하고 관리하는 역할
- 여러 버전의 동일한 패키지를 한 프로젝트에서 사용
- 설치방식 통일
- 패키지 관련 정보가 들어있는 메타 데이터 간소화
- 주요 기능
- 패키지 설치
- Package Manager를 사용해 프로젝트에 필요한 패키지 설치
- 의존성 관리
- Package는 다른 Packge에 의존할 수 있음(Package를 동작시키기 위해 다른 Package가 필수적으로 필요)
- Package Manager는 이러한 의존성을 자동으로 해결해 필요한 Package를 설치
- 버전 관리
- Package Manager는 Package의 버전을 관리함
- 특정 버전의 Package를 설치하고 업데이트 가능
- 프로젝트가 정확한 버전의 Package를 사용하도록 보장할 수 있음
- 스크립트 실행
- 프로젝트에 미리 정의된 스크립트 실행 기능 제공
- 이를 통해 빌드, 테스트, 배포 등의 자동화된 작업 수행
- 패키지 설치
3) Package관리 파일
- package.json
- package 버전 관리 파일
- CLI로 해당 프로젝트가 의존하고 있는 모든 package이름과 버전을 기록
- 설치해야 하는 패키지 → dependencies
개발용 패키지 → dependencies - 설치 커맨드(npm i/yarn i)입력 시 여기 기록된 모든 패키지가 registry로 부터 다운받아져 node_modules에 저장됨
- package.json만 있으면 의존하는 모든 패키지를 설치할 수 있기에 node_modules를 .gitignore파일에 추가
- 설치해야 하는 패키지 → dependencies
- Code
- scripts : npm 명령어 저장, npm run [명령어]로 스크립트 실행
- 설치는 npm install [패키지명]으로 설치, 설치 패키지와 프로젝트 명이 겹치면 안됨
- —save 옵션은 dependencies에 추가하는 명령어, npm v5부터 기본으로 설정
- node_modules
- package.json에 기록된 package들이 실제로 설치되는 폴더
- package-lock.json(yarn.lock)
- package 잠금 파일
- 개발자끼리 서로 다른 버전의 package가 설치되는 것을 막아줌
- → 같은 개발환경을 구성해줌
- 프로젝트에 package가 최초로 추가될 때의 버전 기준
- package.json에서는 버전을 version range(범위)로 명시하기에 정확한 버전은 lock파일에서 정해짐
- package 잠금 파일
2. npm VS yarn
0) npx
- 패키지를 임시로 설치해서 실행하는 용도 → 그래서 CRA에서 사용
1) npm
- 원조 / node.js의 기본 Package Manager
- 그러나 문제점 많(았었)음
- 일관적이지 않은 패키지 버전
- 고정되지 않은 설치 순서
- 병렬화 X 순차적인 설치 → 다운로드 속도가 매우 느림
- 생각 없이 쓰기엔 괜찮음
2) yarn(yarn classic, yarn v1)
- meta(페이스북)에서 제공
- npm의 단점 개선
- 병렬화를 통한 설치 속도 개선
- 자동화 된 lock파일 yarn.lock 생성(npm은 예전엔 안해줬음)
- 의존성 트리 알고리즘 변경
- 캐시 사용
- .yarn/cache를 통해 이미 다운되어 있는 패키지에 대한 정보 저장 → 중복 다운 X
- 현재는 유지 보수만,, 새 프로젝트에서는 사용 권장 X
3. node_modules의 문제점
- 근본적으로 node_modules의 문제 ⇒ 즉 npm과 yarn classic 둘 다 가지는 문제점
1) 모듈 탐색 과정의 비효율
- package를 찾기 위해 순차적으로 상위 디렉토리의 node_modules를 탐색
- 상위 디렉토리의 node_modules에 package가 없다면 계~속 찾아야 함
- 중간의 node_modules가 버전이 다른 의존성을 가지고 있어도 사용해버릴 수 있음
2) 비효율적 설치
- node_modules 디렉토리는 수백MB의 크기와 많은 I/O 작업을 필요로 함
- 이런 복잡하고 깊은 구조로 인해 의존성이 잘 설치되어 있는지 검증하기 어려움
- Yarn Classic과 npm은 기본적인 의존성 트리의 유효성까지만 검증하고 package의 내용은 확인하지 않음
3) 유령 의존성(Phantom Dependency)
- node_modules의 중복 설치로 인한 문제를 개선하기 위해 npm과 yarn classic에서는 Hoisting(끌어올리기)을 사용
- 좌측 트리에서 A(1.0)과 B(1.0)패키지는 두 번 설치되기에 더 많은 공간과 시간이 소모됨
- npm과 yarn은 Hoisting으로 이러한 문제를 해결
- 하지만 직접 의존하고 있지 않은 B(1,0) 라이브러리를 require() 할 수 있게 됨 ⇒ 유령 의존성
- 유령 의존성으로 인해 package.json에 명시되지 않은 라이브러리가 사용 가능해지거나, 다른 의존성을 package.json에서 삭제했을 때 같이 삭제되기도 함 ⇒ 의존성 관리 시스템에 혼란!
4. pnpm VS yarn berry
💡 node_modules의 단점을 개선한 Package Manager
1) pnpm
- Virtual Store
- 모든 패키지를 저장하는 전역 저장소(Virtual Store)에서 패키지를 공유
- 중첩된 패키지는 설치 X ⇒ 전역 저장소에서 가져다 쓰기
- Ghost Dependency 해결(명시한 패키지만 사용)
- 불필요한 I/O 과정을 없애 빠르고 효율적
- 패키지 중복 설치를 하지 않음으로써 사용 용량이 적음
- npm프로젝트에 설치하면 즉시 사용 가능하며, 사용법도 거의 비슷
2) yarn berry(yarn v2)
yarn berry는 크게 두 가지 방식으로 package들을 관리한다.
- Plug’n’Play(PnP)
- 인터페이스 링커 (Interface Linker)
- node_modules 대신, 패키지들에 대한 정보를 zip으로 압축해 .yarn/cache 폴더에 저장
- 이를 찾기 위한 정보는 .pnp.cjs 파일에 생성 후 의존성 트리 정보를 단일 파일에 저장
- 설치 시간 및 용량 감소
- 의존성을 구성하는 파일의 수가 적음 ⇒ 변경 사항 감지 및 삭제 작업 속도 향상
- 인터페이스 링커 (Interface Linker)
- Zero install
- PnP 덕분에 수 백MB크기의 node_modules 대신 커봤자 200MB 정도 크기의 의존성 폴더를 갖게 됨
- github는 파일 당 최대 500MB, 저장소 당 1GB 미만 크기를 권장함
- 의존성 폴더를 통째로 git에 업로드하는 것이 가능해짐
- git clone 이후에 별도의 install 없이 바로 사용 가능
- CI에서 의존성 설치하는 시간이 크게 줄어들어 배포 시간도 단축!
5. 그래서 뭘 쓰는게 좋을지?
- npm
- 단점이 많음(느린 속도, 무거운 node_modules, 유령 의존성 등등,,)
- 하지만 지속적 업데이트로 예전보다는 쓸만함
- node.js의 기본 package manager라 사용 유저도 많고 트러블 슈팅도 쉬움
- yarn classic
- 이미 업데이트가 멈췄고 유지 보수만 하는 상태, 새 프로젝트에서는 사용할 이유가 없음
- pnpm
- Virtual Store를 이용해서 node_modules에서 비롯되는 문제들을 극복함
- npm과 사용법이 비슷하기에(의존성 관리 방법은 전혀 다르지만) 쉽게 사용 가능
- 단 npm보다 사용자가 적어 트러블 슈팅이 어려움
- yarn berry
- pnp를 사용해서 큰 용량인 node_modules를 아예 사용하지 않음
- 그 덕에 zero install 가능 및 git clone 이후 별도의 설치가 필요 없음 → 배포 속도는 가장 빠름!
- 다른 package manager와 다른 pnp 방식을 사용하기에 자잘한 에러가 있을 수 있음
- 다만 PnP방식은 커밋을 하면 .git/objects에 변경된 파일이 zlib으로 압축되어 기록되기에 커밋의 수가 늘어나면 git에 부하가 걸릴 수 있음
모노레포와 보안성 등 더 고려해야할 것이 많은데 이건 추후에 따로 글을 쓰는걸로,,
참조
'Frontend > Etc' 카테고리의 다른 글
액션, 계산 분리해보기(함수형 프로그래밍) (0) | 2024.01.08 |
---|---|
Vite를 사용하면서 svg 컴포넌트로 만들기 (0) | 2024.01.01 |
Eslint와 Prettier 설정하기(React + Ts 사용) (0) | 2023.12.31 |