utils

모노레포(Monorepo) 패키지 매니저

패키지 매니저란, 간단하게 패키지를 편리하고 안전하게 사용하기 위한 툴입니다. 그리고 각각의 패키지들의 의존성(dependency)관리를 가능하게 도와줍니다. 이러한 관리방법은 패키지 매니저(npm/yarn/pnpm) 마다 조금씩 다릅니다. 지금부터 모노레포 관점에서의 패키지 매니저에 대해 알아보도록 합니다.

Frontend Application을 만들 때, 최종 결과물은 HTML, css, javascript로 정적 파일이 될것입니다. 하지만 개발자는 효율적인 개발을 위해 react나 다른 프레임워크나 라이브러리를 사용하고 디버깅을 위해 개발환경에 필요한 도구를 설치하고 설정을 합니다. 이러한 이유로 최종 배포 결과물을 정적 파일로 만들기 위해서는 코드를 트렌스파일, 번들링, 최적화 등의 과정을 거치게 됩니다.

Frontend에서는 개발환경 구축을 위해 Nodejs(server-side runtime)를 사용합니다. nodejs의 패키지 매니저는 npm으로 nodejs를 설치하면 같이 설치가 되게 됩니다. 이러한 패키지 매니저를 통해 개발자들을 다른 사람이 만든 라이브러리를 개발중인 Application으로 가지고 올 수 있고, 새롭게 만든 패키지들도 공유할 수 있게 됩니다. 2010년 정도에 처음 출시가 된 이후에 nodejs 설치 시 기본적으로 npm이 설치가 되기 때문에 가장 많이 사용되는 패키지 매니러자고 할 수 있습니다. npm 의 출시 전에는 dependency를 수동으로 다운로드하고 관리하였기 때문에, npm에서 처음 도입된 package.json과 node_modules의 개념은 굉장한 혁신이라고 볼 수 있습니다.

npm v2의 경우의 의존성 관리는 아래와 같이 중첩된 구조로 관리가 되었습니다.

Monorepo
// Application가 P v1.0 설치
// P v1.0의 의존성이 Y v1.0에 있음
// Y v1.0의 의존성이 H v1.0에 있음
// H v1.0의 의존성이 Y v1.0에 있음
node_module
  - p v1.0
    - Y v1.0
      - H v1.0
        - Y v1.0

위의 구조를 보면 의존성에 따라 중복되는 패키지들도 추가로 설치되는 것을 확인할 수 있습니다. 또한 의존성에 따라 구조가 깊어지는 문제가 발생합니다. 윈도우의 경우는 폴더명 길이 제한이 있기 때문에 깊게 중첩이 되는 경우 장애가 발생하기도 했습니다. 이러한 문제점이 개선된 것이 현재 우리가 사용중인 npm v3이라고 할 수 있습니다. npm v3의 경우는 중첩된 구조가 아닌, 의존성이 있는 모듈들을 같은 deps에서 저장을 합니다. 이러한 방식을 node_module 내부의 플랫하다고 합니다.

Monorepo
// Application가 P v1.0 설치
// P v1.0의 의존성이 Y v1.0에 있음
// Y v1.0의 의존성이 H v1.0에 있음
// H v1.0의 의존성이 Y v1.0에 있음
node_module
  - p v1.0
  - Y v1.0
  - H v1.0
  - Y v1.0

npm을 개선한 버전을 해결하기 위해 새롭게 출시된 것이 yarn(yarn classic)입니다. npm에서 설치 순서에 따라 의존성문제가 발생하는 이슈가 생겼습니다. 이러한 이슈를 해결하기 위해 yarn.lock라는 파일을 도입하였고, 이 파일을 통해 설치 순서에 상관없이 같은 의존성이 생기도록 만들었습니다. 이러한 변화에 따라 npm에서도 package.lock.json이라는 파일이 생겨 동일한 기능을 담당하게 됩니다. yarn은 또한 병렬 설치로 빠른 설치가 가능하고, 워크스페이스 기능도 도입하게 되었습니다. 이러한 워크스페이스 추가는 추후 npm에서도 워크스페이스 개념이 도입되게 됩니다. yarn classic도 node_module의 구조는 플랫합니다. 구조가 플랫하기 때문에 설치하지 않는 패키지도 Application에서 사용이 가능하게 되는 문제가 발생하게 됩니다. 이러한 문제는 예상치 못한 리스크를 유발할 수 있게 됩니다. 현재도 이러한 리스크는 존재합니다. 이러한 리스크를 팬텀 의존성(Phanton Dependency)이라고 부릅니다.

위의 패키지 매니저에 대한 개선을 위해 pnpm이 출시됩니다. npm v3의 플랫 구조에서 중첩 구조를 유지하여 앞에서 말한 리스크를 해결합니다. 하드링크와 스프트링크를 활용하여 성능 향상과 디스크 효율성을 극대화 시키는 특징을 가지고 있습니다. 워크스페이스 기농도 포함되어 있습니다.

2020년에 Yarn에서는 기존(yarn classic)과 완전히 다른 패키지 매니저인 Yarn berry를 출시하게 됩니다. 기존 패키지 매니저와 가장 다른점은 node_module이 없어진 것입니다. 압축 파일을 사용하여 설치 시간 최소화와 제로 인스톨 개념(pnp 개념)을 선보이게 됩니다. yarn berry는 엄격한 의존 관계 관리로 Phanton Dependency와 같은 문제를 유발하지 않습니다. 그리고 yarn 1.x버전은 모두 레거시로 간주되어 yarn classic으로 이름이 변경되었고 유지보수 모드로 변경되었습니다.

정리하면 yarn 출시되면서 Workspace개념이 도입이 되었고, 그 뒤의 패키지에서는 모두 Workspace개념이 추가되어 있습니다. 개발 환경을 위한 도구/소스코드 라이브러리인 패키지를 관리하는 패키지 매니저에 대해 간단히 알아보았습니다. 이제 각각의 패키지 매니저들에 대해 조금 더 디테일 하게 알아봅시다.