📍 모노레포는 모놀리식 애플리케이션(monolithic application)의 한계에 대한 비판에서 출발한다.
1. 미세한 수정에도 기나긴 빌드, 배포 시간을 가지게 된다.
- 내부 컴포넌트의 강한 결속력으로, 미세한 수정에도 프로젝트 전체를 컴파일하고 빌드해야 하기 때문이다.
2. 신규 개발자가 시스템 구조를 파악하기 어렵다.
- 해당 프로젝트를 처음 다루는 개발자에게는 전체 시스템 구조를 파악하고, 개발하는 데 많은 시간이 걸리게 되어 생산성이 떨어진다.
3. 서비스의 관심사 분리가 어려워진다.
- 유기적으로 얽혀있는 코드들은 잘 정리된 정보의 집합으로 나누기 어려워지며, 기존 레거시 코드를 분리하는 작업이 거의 불가능하다.
위 세가지의 한계는 하나의 문장으로 정의할 수 있다.
➡️ "모놀리식 애플리케이션은 모듈화 없이 설계된 소프트웨어 애플리케이션을 말한다."
모놀리식 구조의 한계는 모듈화를 통해 해결할 수 있다.
애플리케이션 로직의 일부를 재사용할 수 있도록 지원하고 전체 교체 없이 애플리케이션의 일부를 수정 또는 교체할 수 있게 유지 관리하는 것을 말한다.
이렇게 만든 모듈을 다른 애플리케이션에서도 사용될 수 있게 독자적 저장소가 있다면 관리가 쉬울 것인데, 이 구조가 바로 멀티레포 이다.
멀티레포는 폴리레포(Polyrepo)라고도 불린다. 모놀리식 애플리케이션을 모듈화하여 별도의 저장소에서 관리하는 구조이다.
이렇게 분리된 프로젝트는 자율성이 높으며 독립적인 개발, 린트, 테스트, 빌드, 게시 배포 파이프라인이 존재하게 된다.
⭐ 현재 가장 보편적으로 사용되는 방법으로 하나의 서비스는 하나의 저장소에서 관리하는 형태이다. 이는 팀의 자율성이라는 큰 이유 때문에 이 방식을 선호한다.
➡️ 장점
1. 다른 프로젝트와 의존성을 갖고 있지 않아 독립적 개발이 가능
2. 모듈화 하여 관심사 분리 편리
3. 강한 오너쉽
➡️ 단점
1. 각 프로젝트의 코드 컨벤션 통일이 어려움
2. 코드 재사용이 어려워 중복 코드가 만들어질 가능성이 높음
3. 번거로운 프로젝트 생성
4. 관리 포인트 증가
- 늘어난 프로젝트의 저장소의 수만큼 관리 포인트가 늘어난다.
5. 일관성 없는 개발자 경험
- 각 프로젝트 마다 고유한 명령 집합을 사용하고, 프로젝트마다의 불일치는 여러 프로젝트에서 사용할 명령을 기억해야 하는 정신적 오버헤드를 만든다.
➡️ 모놀리식 구조의 한계였던 모듈화, 자율성은 해결하지만, 위의 문제들이 생겨난다.
모노레포가 있다.
모노레포 구조란, 하나의 저장소에 여러 프로젝트를 관리하는 구조이다.
흔히 모노레포에서는 프로젝트 사이에 의존성이 존재하거나 같은 제품군이거나 하는 정의된 관계가 존재한다.
1. Unified Versioning
- 하나의 레포는 버전 관리를 한 번에 할 수 있다. 여러 레포로 굴러갈 때는 각자 버전을 관리하다보니 누락되거나 다른 레포와 연결할 대 버전을 계속 확인 및 맞춰줘야 하는 귀찮음이 있지만, 한 레포로 관리하면 아예 버전을 하나로 관리하거나, 여러 모듈의 버전을 관리하기 수월해진다.
2. Extensive Code Sharing & Reuse
- 다른 팀이 만든 코드를 사용해야 할 때가 있는데,(ex. 재사용 되는 디자인 컴포넌트 or 내부 라이브러리) 이를 적절히 공유하고 재사용할 수 있어 효율이 올라간다.
3. Simpolified Dependency Management
- 외부 라이브러리를 사용하는 경우도 있는데, 그런 외부 dependency의 버전을 맞추기 위해 용이해진다.
4. Atomic Changes
- 변경 사항을 Atomic하게 관리할 수 있다. 어떤 변경 사항을 여러 독립된 프로젝트에서 적용해야 하면 한 번에 고쳐서 하나의 커밋으로 관리할 수 있다. 이걸 변화 과정이 원자적이라 말할 수 있다.
5. Large Scale Refactoring
- 여러 독립적인 프로젝트에 적용되어야 하는 변화 사항의 경우 각각 돌아다니면서 고치는 것보다 한 레포에서 고칠 수 있다.
6. Flexible Team Boundaries and Code Ownership
-팀 간 협업이 자유로워진다. 서로 같은 코드 베이스에서 일하고 있기 때문에 변경 사항이 있거나 협업할 일이 있으면 보다 유연하게 코드를 이동할 수 있다. 동시에 코드에 대한 Ownership도 자유로워질 것이다.
생산성을 높이기 위해 여러가지 툴을 제공한다.
🚗 속도 측면의 기능등 (Monorepo Features)
1. Local computation caching
➡️ 같은 머신에서 같은 작업을 두 번 수행하지 않도록 패칭해준다.
2. Local task orchestration
➡️ orchestration이란 컴퓨터 시스템과 어플리케이션에 자동화된 설정 관리 규정들을 의미한다.
➡️ 이를 통해 같은 머신에서 여러 테스크들의 순서와 병렬 처리 여부들을 설정하여 효율적으로 테스크 관리가 가능하다.
3. Distributed computation caching
➡️ 원격 캐싱, 어떤 머신에서든 한 번 실행된 작업은 원격 저장소에 캐싱되어 다른 머신에서도 이를 사용하여 빠른 작업 수행이 가능해진다.
➡️ 매번 다른 원격 머신을 사용해야 하는 CI 작업 등에서 좋은 효과를 낼 수 있다.
4. Detecing affected projects / packages
➡️ 변경된 프로젝트 감지
➡️ 어떠한 프로젝트가 변경되면 이에 영향을 받는 프로젝트를 감지하는 기능을 갖고, 어떤 변경 사항이 있을 대 전체 프로젝트를 모두 빌드하지 않고 영향 받는 프로젝트만 감지해서 특정 작업을 수행할 수 있도록 한다.
🔑 관리 측면의 기능들
1. Source code sharing
➡️ 프로젝트간 코드 공유 가능
2. Code generation
➡️ 스페폴딩들의 코드 생성을 쉽게 하게 해준다.
3. Project constraints and visibility
➡️ 프로젝트 간의 의존성 관계를 제한하는 규칙을 설정할 수 있도록 도와준다.
➡️ 프라이빗으로 설정한 프로젝트들은 다른 프로젝트들에서 참조를 할 수 없게 된다.
사실 멀티레포의 단점이 모노레포의 장점이고, 장단점이 교차하기 때문에 적절한 상황에서 사용해야 한다.
a. 빌드 시간 증가 : 모든 프로젝트를 함께 빌드해야 하므로 빌드시간이 증가할 수 있다. (bundle size)
b. 복잡성 증가 : 여러 프로젝트를 하나의 저장소에서 관리하므로 코드 충돌 등의 문제가 발생할 가능성이 높아진다.(management)
c. 변경 사항이 모든 프로젝트에 영향을 미침 : 하나의 프로젝트에서 발생한 변경 사항이 전체 시스템에 영향을 미칠 수 있다.(code convention)
모노레포의 가장 큰 장점은 프로젝트 사이의 코드 공유가 간편하다는 것이다.
이 장점을 최대한 활용할 수 있는 상황에서 모노레포를 사용하는 것이 좋다.
=
참고자료:
https://spookyjelly.tistory.com/80
https://d2.naver.com/helloworld/0923884#ch1
https://blog.hwahae.co.kr/all/tech/11962
https://medium.com/musinsa-tech/journey-of-a-frontend-monorepo-8f5480b80661
https://medium.com/hcleedev/dev-monorepo-%EA%B0%9C%EB%85%90-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-33fd3ce2b767