Skip to content

Commit

Permalink
Create 19-2.md
Browse files Browse the repository at this point in the history
  • Loading branch information
newminkyung authored Jun 16, 2024
1 parent 7db7a2c commit f207cfa
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions new/19-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
## monorepo

> A monorepo is a single repository containing multiple distinct projects, with well-defined relationships. - Nrwl
- 모노레포를 이루는 개별 프로젝트(애플리케이션, 패키지)들은 독립적(distinct)이어야한다.
- 정상적인 구조의 모노레포라면 모노레포를 폴리레포로 바꾸어도 개별 프로젝트들이 의존성 문제 없이 다 분리될 수 있어야한다.
- 모노레포 위에서 각 패키지-애플리케이션, 패키지-패키지 관계에서의 의존성이 복잡하고 관리될 수 없는 형태라 각 프로젝트들이 독립적인 배포가 힘들다면 단순히 프로젝트 여러개가 한 레포지토리에 모여있는 모놀리식과 동일하다.

- 모노레포는 단순히 code-colocation이 아니기 때문에 각 프로젝트의 관계가 잘 정의되어야한다.
- 모노레포의 프로젝트들이 패키지-패키지, 패키지-애플리케이션 관계를 이루고 있다면 의존 관계가 필연적으로 발생
- 각 프로젝트들은 의존 관계가 쉽게 추적될 수 있도록 패키지에는 버저닝이 필요
- 특정 패키지 의존을 강제하거나 혹은 의존할 수 없도록 통제할 수 있는 도구가 필요

### 모노레포의 장점

#### 1. 거대한 프로젝트의 코드 관리 비용을 줄이낟.

- 모노레포는 여러 프로젝트 간 일관된 개발자 경험을 제공할 수 있다.
- 폴리레포였다면 따로 따로 세팅해줘야할 린트, 테스트, 빌드 도구들을 모노레포에서 관리하면 단일한 config로 관리할 수 있다.

#### 2. 특정 패키지의 코드를 쉽게 확인하고 변경을 쉽게 적용할 수 있다.

- 내부 패키지 코드와 애플리케이션 코드가 한 곳에 있다면, 패키지 단의 코드 변경을 쉽게 적용할 수 있다.
- 폴리레포에서는 패키지를 수정했을 대 이를 배포하고, 애플리케이션 레포지토리로 옮겨 코드를 수정 -> 검증 -> 빌드하는 과정이 순차적으로 이루어지기 때문에 모노레포 구조보다 번거롭다.

### 모노레포의 단점

위의 장점이 있음에도 모노레포에서는 하나의 큰 레포지토리가 필연저긍로 가질 수 밖에 없는 복잡성, 코드 탐색의 난이도 상승 등 새로운 단점들을 고려해야하다.

#### 1. 레포지토리의 큰 용량

- 거대한 프로젝트들을 모노레포로 관리한다면 코드가 너무 많기 때문에 CI/CD 단에서 이루어지는 레포지토리 chekcout 성능에 큰 부하가 발생
- 따라서 CI, CD 머신에서 코드를 다운받는 시간을 최적화할 수 있는 방법이 필요
- `git` 명령어를 통해 chekcout을 최적화할 수 있다.
- `shallow clone`을 사용해 특정 커밋 기준의 파일 형상만 가져올 수 있거나, `partial clone`을 통해 최신 커밋 기준으로 가져오되 변경 이력을 함께 chekcout할 수 있다.

```bash
# partial clone
$ git clone [레포지토리_주소] --filter=blob:none
# shallow clone
$ git clone [레포지토리_주소] --depth 1

# 특정 디렉토리만 가져오는 방법
git sparse-checkout init --cone
```

#### 2. 의존성을 추가, 수정하기 쉽다

- 개별 레포지토리에서는 임의로 코드 의존 관계를 설정해도 다른 프로젝트에 영향을 미치지 않지만, 모노레포 환경에서는 영향을 크게 미치는 상황이 발생할 수 있다.
- 따라서 모노레포에서는 패키지 의존성과 참조를 감시할 수 있는 컨벤션이 필요하다
- yarn workspace를 사용하면 `Contraints`를 사용해 패키지간 의존성 규칙을 제공할 수 있다.
- turborepo는 정의된 명령을 수행할 때 순환참조가 발생한 패키지 의존 관계를 잡아준다.
- turborepo에서는 패키지 의조성간의 관계를 시각적으로 보여줄 수 있는 툴이 있음

#### 3. 의존하고 있는 애플리케이션을 파악하기 어렵다.

- 패키지와 애플리케이션 코드가 모두 한 곳에 있는 모노레포에서는 특정 하위 패키지의 코드가 바뀌었을 때, 최종적으로 어떤 애플리케이션이 배포되어야하는지 파악하기 힘들 수 있다.
- 따라서 해당 패키지에 의존하고 있는 애플리케이션을 모두 찾아 빌드, 배포를 할 수 있는 도구가 필요하다
- turborepo는 `Topological Dependency`를 추적하여 특정 태스크들을 수행할 수 있다.

```json
// tubo.json

{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"] // 빌드 결과물
}
}
}
```

- 특정 애플리케이션을 빌드하게 되면 의존하는 하위 패키지부터 다시 빌드한다.

#### 4. 여러 패키지와 앱 간에 같은 태스크를 여러번 수행해야 할 수 있다

- 모노레포에서는 여러 프로젝트에 대한 빌드, 린트, 테스트 수행이 수시로 일어난다.
- turborepo는 빌드 태스크들은 모두 캐시되어 코드의 형상이 바뀌지 않았을 때 해당 패키지를 다시 빌드할 일이 생기는 경우 캐시를 사용하여 빠른 시간안에 빌드한다.

0 comments on commit f207cfa

Please sign in to comment.