본문 바로가기

3주차

패키지 Manager~ 그게뭘까?

패키지 매니저란?

패키지 매니저는 패키지를 다루는 작업을 편리하고 안전하게 수행하기 위해 사용되는 툴을 말한다.

 

더 간단히 얘기하면 JavaScriptTypeScript 를 사용하면서 발생하는 requireimport 구문을 사용하는 외부 의존성 참조를 올바르게 참조할 수 있도록 보장해주는 프로그램이다

import React from '/Users/raon0211/path/to/react/index.js';
import { sum } from '/Users/raon0211/path/to/@toss/utils/index.js'


JavaScript 표준에 따르면, 원래는 정확한 절대경로나 상대 경로를 통해서만 `import` 할 수 있었지만, 이렇게 쓰다보면 개발자 경험에 좋지 않은 영향을 준다.

 

그래서 우리는 보통 이런식으로 import 문을 작성한다

import React from 'react';
import { sum } from '@toss/utils';

 

하지만 이렇게 하면 문제가 발생할 수 있다. 예를 들어 react 가 정확히 어떤 버전인지, @toss/utils 이 어떤 버전인지 명확히 알 수 없다는 것이다.

 

React 에는 여러가지 버전이 존재하기 때문에 정확한 정보의 제공이 필요한데, 그런 정확한 버전 정보 를 일반적으로 pakage.json 파일에 의존성을 명시하고, npm 또는 yarn 을 이용해서 의존성의 명시된 버전을 설치하는 것이다.

 

패키지 매니저가 앞서 이야기 한 모호한 버저닝 문제를 해결해주는 것

패키지 매니저의 동작단계

그렇다면 패키지 매니저는 어떤 방식으로 동작할까?

Yarn 을 포함한 패키지 매니저는 Resolution Fetch Link 세 단계로 동작한다.

Resolution 단계

  • 라이브러리 버전 고정
  • 라이브러리의 다른 의존성 확인
  • 라이브러리의 다른 의존성 버전 고정

첫 번째 단계인 Resolution 단계는 어떠한 문제를 해결하는 단계 를 말합니다. 첫 번째 문제는 라이브러리를 정확한 버전으로 고정하는 문제입니다.

 

패키지 매니저는 Resolution 단계에서 pakage.json 파일에 명시된 버전 범위에 따라 정확한 버전을 결정합니다.

구체적으로 예를 들면, react 18.2.0 이라고 명시되어 있으면, 패키지 매니저의 규칙에 따라 ≥ 18.2.0, <19 사이의 어떠한 버전이든 사용할 수 있는 것이다.

 

패키지 매니저는 저 범위를 만족하는 선에서 가능한 최신 버전을 사용하려고 하는 것이다.

 

그리고 그 다음은 설치한 라이브러리가 사용하는 다른 라이브러리 즉, 의존성의 의존성을 확인하는 작업을 가집니다.

그리고 마지막으로는 의존성의 의존성 의 버전도 고정하는 것이 Resolution 단계라고 할 수 있다.

 

그래서 다시 정리하자면, Resolution 단계는 모든 기기에서 고정된 버전을 사용할 수 있도록 하는 것이다. 의존성 버전을 모두 고정시키고, 그 의존성의 의존성 을 다 찾아내서 그 버전도 고정시키는 것.

 

그리고 그 결과물이 yarn.lock 이나 package-lock.json 에 저장된다.

 

Fetch 단계

Fetch 단계는 한 줄로 요약하면 결정된 버전의 파일을 다운로드 하는 과정 을 말하는 것이다.

방금 전 yarn.lock 에 명시된 패키지를 네트워크를 통해 필요한 파일들을 가져온다.

Link 단계

Link 단계는 Resolution/Fetch 된 라이브러리를 소스 코드에서 사용할 수 있는 환경을 제공하는 과정을 말한다.

npm Linker

우리에게 가장 익숙한 node_modules 기반의 Linker는 pakage.json 에서 명시하는 모든 의존성을 그냥 node_modules 디렉토리 밑에다가 하나하나씩 써버리는 것이 npm Linker의 역할이다.

 

예를 들어 소스 코드에서 특정한 라이브러리를 사용한다면, 루트 폴더 하위의 node_modules 에 해당 패키지를 추가하고, 추가 된 패키지에도 node_modules 가 있다면 다시 깔아주는 것이 npm Linker가 하는 일이다.

 

이 방식에는 꽤나 많은 단점이 존재하는데, 일단 패키지를 찾는 것이 어려울 수 있다. 이 단점은 개발자 뿐만 아니라 npm Linker에게도 적용되기 때문에, 당연히 importrequire 하는 속도가 느려지는 것이다.

 

그리고 디렉토리의 크기가 너무 커지는 단점이 있다. 예를 들어 만약 100개의 프로젝트에서 혹은 폴더에서 React 18.2.0 버전을 사용한다고 하면, 정말로 100번씩 해당 버전이 추가되는 것이다.

 

그래서 우리가 잘 알고 있는 호이스팅 이라는 방법을 사용하기도 하는데, 최적화가 완전히 되는것은 아니기 때문에 좋은 해결방법은 아닌 것이다.

Yarn

반면에 yarn은 패키지 매니저의 각 구성요소가 모듈화되어 있고, 인터페이스가 잘 분리되어 있기 때문에, Resolution 단계의 코드와 Fetch 단계 , Link 단계의 코드가 섞여있지 않고 모듈화 되어있는 것은 yarn PnP 밖에 없다.

 

더 자세하게 얘기하자면, npm은 모든 의존성을 node_modules 폴더 아래에 설치하고, 트리 형태로 하위 의존성도 폴더 내부에 중첩시킨다.

 

반면에, Yarn PnP 방식은 node_modules 없이 직접 패키지들을 참조하고, .pnp.js 파일을 참조하여 의존성 위치를 추적할 수 있다.

 

그리고 두 번째 장점은 성능 이다 PnP는 파일 I/O의 수가 적고, 설치 과정이 간단하기 때문에 속도가 매우 빠른편이다.

그 설치과정을 살펴보면, npm 같은 경우 pakage.jsonpakage-lock.json 에 따라 의존성 버전을 확인하고 모든 의존성node_modules 폴더 하위에 설치하고, 각 하위 의존성도 중첩하여 node_modules 내에 폴더 구조를 생성한다.

 

반면에 Yarn Pnp 방식은 pakage.jsonyarn.lock 파일을 참고하여 의존성 버전을 고정하고, 모든 의존성 파일을 로컬 캐시 에 저장한다. 이 캐시 파일들은 Yarn 이 직접 관리 하므로, node_modules 폴더가 필요 없는 것이다.

 

즉, 폴더 생성 및 중첩 없이 .pnp.js 파일 하나만으로 의존성을 관리하므로 파일 I/O 의 수가 적고 속도가 빠른것.

 

그리고 마지막 장점은 확장 가능성 인데, Yarn은 코어 부분을 제외하면 전부 플러그인화가 되어 있어서, 다양한 기능을 쉽게 추가할 수 있다는 장점이 있다. 그래서 조직 내에서 자체적으로 여러 플러그인을 만들어서 사용하는 것이 가능하다.

'3주차' 카테고리의 다른 글

[React] Custom Hook  (0) 2024.11.01
[React] useEffect 훅과 의존성 배열  (0) 2024.11.01
리액트 컴포넌트의 Lifecycle  (0) 2024.11.01
[3주차] JSX 알아보기  (0) 2024.10.31
리액트가 처음인 당신께...  (3) 2024.10.29