CRA 없이 리액트 시작하기-(1) 패키지 매니저 정하기

가연·2024년 7월 13일
2

우테코

목록 보기
3/10
post-thumbnail

이번 프로젝트에서는 CRA, Vite 등을 활용하지 않고 직접 리액트 개발환경을 셋팅해주었다.

간단한 초기 설정을 하기 위해 다음과 같은 플로우로 진행했다.
1. 패키지 매니저 정하기
2. 웹팩, 플러그인, 로더 설치
3. webpack.config.js, tsconfig 설정
4. public 폴더 추가 및 App.tsx, index.tsx 파일 추가
5. eslint,prettier 설치 및 설정

📦 패키지 매니저 정하기

수많은 패키지를 효율적으로 설치, 삭제, 업데이트하기 위해 패키지 매니저가 필요하다. 그렇다면 coduo 에서는 어떤 패키지 매니저를 선택했을까?

NPM vs YARN

NPM

node.js의 모든 패키지와 모듈을 관리하며 CLI 클라이언트 npm으로 구성된다.

  • 2010년에 개발
  • 별도로 설치할 필요 없다.
  • 관련 커뮤니티가 많이 활성화되어있어 접근성이 좋다
  • 패키지를 한 번에 하나씩 순차적으로 설치
  • 자동으로 패키지에 포함된 다른 패키지 코드를 실행 (보안 시스템에 몇 가지 취약성이 발생)

YARN

  • 2016년 페이스북에서 개발한 패키지 관리자
  • 속도나 안정성 측면에서 npm보다 향상(물론 최근 버전 npm 과 비교했을때는 차이점 거의 없음)
  • 여러 패키지를 동시에 가져오고 설치하도록 최적화(병렬적 설치)
  • yarn.lock 또는 package.json파일에 있는 파일만을 설치 → 매 설치마다 같은 버전의 의존성을 설치하도록 보장하여 버전 차이로 생기는 버그 방지(npm 도 최근에 package.lock.json 제공)
  • 가독성이 좋다.

💡 우리의 목표는 라이브러리를 많이 쓰고, 커뮤니티를 많이 보는 것이 아닌 최대한 성능적으로 프로젝트를 개선하는 것이므로 Yarn 을 선택했다.

+ 의존성 관리 기법

npm(v3^), yarn : 호이스팅 기법

npm v2 이전에서는 패키지들을 설치할 때 중복되는 패키지들이 생성되어 디스크 공간을 낭비할 수 있다는 단점이 있었다.

그래서 이를 막기 위해 v3과 yarn 에서는 호이스팅을 활용하여 트리를 flat 하게 만들게 되었다. 하지만 충돌할 수 있는 패키지는 상위 모듈 아래에 두기 때문에 유령 의존성이 발생할 수 있다.

💡 유령 의존성
직접 의존하고 있지 않은 라이브러리를 require() 할 수 있는 현상. 위의 그림에서 package-1 이 B(2.0) 을 require 할 수 있게 됨.
다른 의존성을 package.json 에서 제거했을 때 소리없이 같이 사라지기도 해서 예측하기 어렵다.

유령 의존성을 해결하기 위해 다음과 같은 패키지 매니저가 등장했다.

yarn Berry : PnP(Plug’n’Play)

yarn Berry 는 패키지 의존성을 node_modules 폴더에 저장하지 않고 .zip 파일로 압축하여 .yarn/cache 에 저장한다. 그리고 이를 찾기 위한 정보를 .pnp.cjs 파일에 기록한다.

.pnp.cjs를 이용함으로써 별도의 디스크 I/O 작업 없이도 패키지의 위치를 정확히 알 수 있기 때문에 시간도 단축되고, 중복 설치를 방지하며, node_modules를 만들고 패키지들을 호이스팅 시킬 필요가 없다.

장점

  • zero-install : git clone 이후나 branch 이동 시에도 별도 설치(npm install , yarn install ..) 없이 바로 사용이 가능하다.
  • CI 에서 의존성 설치하는 시간이 절약된다.
    • 기존에는 node_modules 가 너무 무거워서 .gitignore 에 포함되고 package.json에 기록된걸 각자 로컬에서 다운 받는 방식
    • 네트워크에서 패키지를 다운로드 받는 시간이 사라지므로 보통 분 단위로 과금하는 CI/CD 솔루션을 사용할 때 비용 절감 효과를 볼 수 있다.

단점

  • PnP를 지원하지 않는 패키지가 존재한다
    • 만약 pnp 를 지원하지 않는 패키지가 필요하다면 node_modules 가 생성되기 때문에 yarn-Berry 의 장점을 누릴 수 없다.
  • PnP가 Git에 지속적으로 영향을 줄 수 있다. (작업한 뒤 커밋을 하면 .git/objects 내에 변경된 파일이 zlib으로 압축되어 영구히 기록으로 남는다)
    • 커밋 수가 많을 수록, 커밋의 파일 용량 수가 많을 수록 이후의 작업에서 Git의 체크아웃, 브랜칭 속도에 영향을 줄 수도 있다고 한다.(https://hiddenest.dev/yarn-pnpm-3)

pnpm

node_modules를 직접 설치하는 대신, 전역 저장소(Virtual Store)에서 패키지를 공유하는 구조를 사용한다.

  • content-addressable file store : pnpm 은 홈 디렉토리의 글로벌 저장소인 ~/.pnpm-store 에 모든 패키지를 저장하는 저장소를 두고, 중첩된 패키지는 단 한번만 설치한다.

즉 파일 이름으로 파일에 접근하지 않고 각 의존성 파일에 해시값을 부여해 관리한다. (중복 패키지는 동일한 해시 id)

프로젝트마다 node_modules 폴더에 symbolic(sym) link 를 만들어 연결

⇒ npm v2 처럼 중첩 구조, 중복된건 같은 해시값으로 !

  • yarn 보다 간단하게 모노레포 설정이 가능하다.

레퍼런스

https://engineering.ab180.co/stories/yarn-to-pnpm

https://velog.io/@seobbang/패키지-매니저-npm-yarn-pnpm-yarn-berry

yarnBerry 나 pnpm 도 사용해보고 싶었지만 지금 프로젝트에서는 장점을 크게 느끼지 못할 것 같아 yarn으로 진행하기로 했다. 만약 불편하다고 느끼게 되거나 확실한 이유를 찾으면 마이그레이션 하기로 결정했다.

🖇️ devDependency vs dependency

패키지 매니저를 정했으니 여러 패키지들을 설치해 주어야 하는데, 어떤것을 devDependency 로 설치해주어야 하는지 조금 헷갈렸다. 그래서 자세히 알아보았다.

devDependency

  • 설치 yarn add -D 라이브러리명

로컬 환경에서 개발 및 테스트에만 필요한 패키지들이 정의되어 있다.

devDependencies에 포함된 라이브러리는 실제 배포할 때 포함되지 않기 때문에 빌드 시간을 줄일 수 있다.

ex) eslint, prettier ,react-dom, @types/jest, vite, file-loader, typescript …

Dependency

프로덕션 환경에서 응용 프로그램을 실행시키기 위한 패키지들이 정의되어있다.

ex) @emotion/react, react-dom, @tanstack/react-query …

3개의 댓글

comment-user-thumbnail
2024년 7월 16일

글씨체 어떻게 한거에요?

1개의 답글