-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7db7a2c
commit f207cfa
Showing
1 changed file
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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는 빌드 태스크들은 모두 캐시되어 코드의 형상이 바뀌지 않았을 때 해당 패키지를 다시 빌드할 일이 생기는 경우 캐시를 사용하여 빠른 시간안에 빌드한다. |