# Monorepo

## Monorepo

> **잘 정의된 관계를 가진** 여러 개별 프로젝트가 포함된 단일 리포지토리
>
> 하나의 큰 프로젝트를 적절한 모듈로 나누고 모듈간의 의존관계를 잘 정의해야 한다.

{% hint style="info" %}
모노레포를 사용 중인 오픈 소스

* [babel](https://github.com/babel/babel)
* [primitive](https://github.com/radix-ui/primitives)
  {% endhint %}

### 특징

* 모노리포 내의 루트 워크스페이스는 각각의 워크 스페이스를 관리하는 역할을 한다.
* 루트 워크스페이스와 각각의 워크스페이스가 가지고 있는 외부 의존성은 효율적으로 관리되어야 한다. (with Package Manager)
  * 각각의 Package manger는 외부 의존성을 설치하는 방식과 동작하는 방식이 서로 다르다
* 각각의 워크스페이스는 **유기적으로 작업되기 때문에 패키지 간 의존 관계가 명확해야 하고** 의존성을 바탕으로 테스크를 수행해야 한다.&#x20;
* 각각의 워크스페이스는 앱으로 실행될 수 있고, 모듈의 역할로서 다른 모듈이나 앱에서 사용될 수 있다.&#x20;
  * 모듈은 npm 패키지와 같은 형태로 제작되어야 함
* 모듈인 워크스페이스는 패키지로 명확하게 노출한다.

### 장점

* 모노리포 내의 내가 담당하지 않는 프로젝트여도 자유롭게 개선을하고 PR을 올릴 수 있음
* 동료들간의 코드와 리소스를 쉽게 공유하므로 기술적이든 비지니스적이든 성장 할 기회가 많이 열린다.
* 여러 프로젝트들이 코드들을 공유하고 재사용하기 때문에 중복 작업을 줄이고, 개발 시간을 절약할 수 있다.
* 각 프로젝트마다 설정이 일관적이고 동일한 개발자 경험을 가지게 되어 관리하기 쉬워진다.
* 전체 히스토리가 한번에 보인다.

### 단점

> Monorepo의 단점들은 역으로 Multirepo의 장점이 된다.
>
> [폴리리포주의자'가 모노리포를 반대하는 3가지 이유](https://www.itworld.co.kr/insight/214234)

* Mono repo를 위한 추가적인 러닝커브 발생
* Multi repo보다 상대적으로 의존성 연결이 쉬워 과도한 의존 관계가 나타날 수 있다.
* 하나의 CI를 구성할 수 있지만 방법이 복잡하다.
* 리포지토리 자체가 빠르게 무거워진다.&#x20;
* 모든 코드가 리포지토리 하나에 밀집되어 있어 사소한 문제가 크리티컬한 문제가 될 수 있다.&#x20;
  * 여러 곳에 영향을 주는 코드들은 그 코드에 영향을 받는 코드 담당자들과 면밀히 검토하는 과정이 필요
* 코드 관리 및 소유권 등의 문제가 생길 수 있다.
* 대규모 리팩토링이 쉬워지는게 장점이자, 단점

### MFA는 Monorepo가 꼭 필요한가?

> MFA는 Monorepo가 필수는 아니지만 여러 프로젝트를 잘 정의된 관계를 가지도록 개발해야하기 때문에 좋은 옵션이 된다.&#x20;

* MFA는 여러 프로젝트가 하나의 큰 프로젝트로 구성이되는 아키텍처이기 때문에 여러 프로젝트가 필요하다.
* 프로젝트들이 잘 정의된 관계로 구분되어 있다.
  * 공통으로 쓰는 코드들은 별도의 모듈로 패키지화해서 사용하고 이러한 패키지는 의존 관계를 명확히 가지고 있어야 한다.
  * 수정된 패키지가 어떤 마이크로 앱에 영향을 주는지 확실히 알아야 한다. → 배포의 범위를 결정

{% hint style="info" %}
잘 정의된 관계를 그래프로 도식화해서 어떤 마이크로앱들이 배포가 정확히 되어야하는지 판단할 수 있어야한다.
{% endhint %}

### Monorepo !== Monolith&#x20;

> Monolith repo란 하나의 리포지토리 안에 하나의 앱에 관련된 모든 코드와 리소스를 넣어 관리하는 방식

* 하나의 앱을 하나의 프로젝트로 관리하는 것
* 프로젝트 하나안에 페이지, UI 컴포넌트, 상태 로직, 서버 데이터 처리 등 모든 것들이 들어있다.

### Modular repo

> 소스 코드를 관심사에 맞게 여러 모듈로 나누어 패키지로 만들고 패키지 간 필요한 패키지를 가져다 쓰는 방식

* 패키지 간 잘 정의된 관계가 없다면 `Monorepo`가 아니다
* 패키지 간 **잘 정의된 관계**로 여러 패키지를 하나의 리포지토리에 관리하는 방식이 `Monorepo`

### Multi repo(Poly repo)

> 여러 모듈로 나눈 패키지를 각각의 리포지토리로 관리하는 방식
>
> 즉, 여러 개의 리포지토리가 서로 유기적인 관계를 가지면서 개발하는 방식

### Multi repo 단점

> Multi repo의 단점들은 역으로 Monorepo의 장점이 된다.

* 참조하고 있는 다른 리포지토리의 코드가 수정되거나 버그가 있는 경우 해당 리포지토리 모듈을 버전업을 하여 사용해야 해서 번거롭다.
* 히스토리가 한번에 보이지 않는다.&#x20;
* A1에서 A2의 기존 코드를 활용하려는 경우 의존성 흐름을 관리해주어야 하기 때문에 해당 코드를 따로 관리하는 리포지토리를 새로 생성해서 관리해주어야 하므로 추가 비용 발생이 발생한다.&#x20;
* 각 프로젝트마다 설정이 일관적이지 않아 컨텍스트 스위칭과 유지보수 맥락 흐름이 끊긴다.
