What tools are in Monorepo?
Bazel (by Google), Gradle Build Tool (by Gradle, Inc), Lage (by Microsoft), Lerna, moon (by moonrepo), Nx (by Nrwl), Pants (by the Pants Build community), Rush (by Microsoft), and Turborepo (by Vercel).
모노레포가 무엇을 제공해줄까요?
새 프로젝트를 만드는 데 드는 오버헤드가 없습니다.
기존 CI 설정을 사용하고, 모든 소비자가 동일한 저장소에 있는 경우 버전이 지정된 패키지를 게시할 필요가 없습니다.
프로젝트 전반에 걸친 원자적 커밋
커밋할 때마다 모든 것이 함께 작동합니다. 동일한 커밋에서 모든 것을 수정할 때 획기적인 변경 같은 것은 없습니다.
모든 것의 단일 버전
타사 라이브러리의 충돌 버전에 따른 프로젝트로 인한 비호환성에 대해 걱정할 필요가 없습니다.
개발자 이동성
다양한 도구와 기술을 사용하여 작성된 애플리케이션을 일관된 방법으로 구축하고 테스트하세요. 개발자는 자신있게 다른 팀의 애플리케이션에 기여하고 변경 사항이 안전한지 확인할 수 있습니다.
그 외 장점
💡 로컬 컴퓨팅 캐싱
파일을 저장 및 재생하고 작업 출력을 처리하는 기능입니다. 동일한 머신에서는 동일한 것을 두 번 빌드하거나 테스트하지 않습니다.
로컬 작업 오케스트레이션
작업을 올바른 순서로 병렬로 실행하는 능력. 나열된 모든 도구는 더 제한적인 Lerna를 제외하고 거의 동일한 방식으로 이를 수행할 수 있습니다.
분산 계산 캐싱
다양한 환경에서 캐시 아티팩트를 공유하는 기능. 이는 CI 에이전트를 포함한 전체 조직이 동일한 것을 두 번 구축하거나 테스트하지 않는다는 것을 의미합니다.
분산 작업 실행
단일 시스템에서 명령을 실행하는 인체공학적 특성을 대부분 유지하면서 여러 시스템에 명령을 배포하는 기능입니다.
투명한 원격 실행
로컬에서 개발하는 동안 여러 컴퓨터에서 모든 명령을 실행할 수 있는 기능입니다.
영향을 받는 프로젝트/패키지 감지
영향을 받는 프로젝트만 빌드/테스트하려면 변경으로 인해 영향을 받을 수 있는 항목을 결정합니다.
작업공간 분석
별도의 설정 없이 작업공간의 프로젝트 그래프를 이해할 수 있는 기능.
종속성 그래프 시각화
프로젝트 및/또는 작업 간의 종속 관계를 시각화합니다. 시각화는 대화형이므로 그래프의 노드를 검색, 필터링, 숨기기, 초점/강조 표시 및 쿼리할 수 있습니다. (Turborepo Graphviz)
소스코드 공유
개별 소스 코드 조각의 공유를 촉진합니다.
일관된 툴링
이 도구는 프로젝트 개발에 사용하는 대상(다양한 JavaScript 프레임워크, Go, Rust, Java 등)에 관계없이 일관된 경험을 얻을 수 있도록 도와줍니다.
즉, 이 도구는 다양한 기술을 동일한 방식으로 처리합니다.
예를 들어 이 도구는 package.json 및 JS/TS 파일을 분석하여 JS 프로젝트 deps와 이를 빌드하고 테스트하는 방법을 파악할 수 있습니다. 그러나 Rust에 대해 동일한 작업을 수행하기 위해 Cargo.toml 파일을 분석하거나 Java에 대해 동일한 작업을 수행하기 위해 Gradle 파일을 분석합니다. 이를 위해서는 도구를 연결할 수 있어야 합니다.
코드 생성
코드 생성에 대한 기본 지원
프로젝트 제약 및 가시성
저장소 내의 종속 관계를 제한하는 규칙 정의를 지원합니다. 예를 들어 개발자는 일부 프로젝트를 팀 전용으로 표시하여 다른 사람이 해당 프로젝트에 의존할 수 없도록 할 수 있습니다. 개발자는 사용된 기술(예: React 또는 Nest.js)을 기반으로 프로젝트를 표시하고 백엔드 프로젝트가 프런트엔드 프로젝트를 가져오지 않도록 할 수도 있습니다.
이전엔 무엇을 사용하였고 무엇과 비교하여 고려하는가?
이전에는 lerna, 가장 최근에는 turborepo를 사용하여 프로젝트를 진행하였다. 다른 목표를 갖고 있는 많은 솔루션이 많지만, lerna는 deprecated 되었고 maintain 하고 있는 회사인 Nrwl에서는 Nx를 밀어준다. Rush 도 각광 받고 있지만 large monorepos with lots of teams and projects 는 우리와 거리가 있는 내용 같다. 만족도가 높았던 turborepo와 원래부터 monorepo의 강자 Nrwl의 Nx를 비교해볼까 한다.
(Bazel 구글 진영이라 Angular 관련 커뮤니티만 보이고, MS의 large는 커뮤니티가 너무 작아보인다. )
Few key differences
Note that the relationship between Nx and Turborepo isn’t the same as with Nx and say Yarn workspaces or Lerna. Nx and Yarn workspaces are complementary, so it makes sense to use both in some situations. Turborepo is a subset of Nx (at this point), so we don’t think it makes sense to use both.
와 같은 이유로 Yarn Workspace 는 제외하였습니다.
TurboRepo Nx
Adoption | package-based | packaged based or integrated apporach |
프로젝트 그래프 시각화 | graphviz 있지만 안이쁨 | 이쁘고 vscode plugin도 좋다 |
Workspace | package.json 파일만 분석 | pakcage.json + JS/TS 파일도 분석하여 구성 |
Module Boundaries (다른 프로젝트가 다른 프로젝트 내의 파일에서 변수를 가져오려고 하면 Linting 중에 오류가 발생) | X | O |
Detecting affected projects/packages | O | O |
Local task coordination | O | O |
Local computation caching | O | O |
분산 작업 실행 | X | 단일 시스템에서 작업을 병렬화할 수 있을 뿐만 아니라 작업을 여러 시스템에 완전히 자동으로 배포. |
모든 작업은 올바른 순서로 실행되고 터미널 출력은 모두 한 곳에 있으며 오류는 모두 한 곳에 있습니다. 파일은 모두 한 곳에 있습니다. | ||
bechmark(https://github.com/vsavkin/large-monorepo/) | 상대적으로 느림 | 상대적으로 빠름 |
setup | simple | complicated |
캐싱 | 좋음 | 상대적으로 더 뛰어남 |
플러그인 | X | O |
****Turborepo는 "패키지" 측면에서 생각하는 경향이 있는 반면 Nx는 많은 경량 프로젝트에 중점을 둡니다. 대규모 Nx 작업공간은 수백 또는 수천 개의 프로젝트로 구성되는 경향이 있으며 이는 세 가지 측면에서 평균 빌드 성능에 도움이 됩니다.
- 그래프의 더 작은 부분이 평균적으로 영향을 받습니다.
- 부분 캐시 적중 가능성이 더 높습니다.
- 분산 작업 실행은 에이전트 전체에 작업을 배포하는 방법에 있어 더 많은 유연성을 제공합니다
package based repo
package.json 그리고 node_modules 를 통해 서로 의존하는 패키지 모음
package-based/
├── packages/
│ ├── is-even/
│ │ ├── index.ts
│ │ └── package.json
│ └── is-odd/
│ ├── index.ts
│ └── package.json
├── nx.json
└── package.json
이미 단일 저장소(예: Yarn/npm/pnpm 작업 공간)가 있고 주로 속도 및 작업 예약을 위해 Nx를 원하는 경우에 이상적입니다. 또한 Nx를 방해하지 않고 모든 것을 스스로 설정하기를 원하는 경우에도 마찬가지입니다.
Integrated Repos
통합 저장소에는 표준 import 문을 통해 서로 의존하는 프로젝트가 포함되어 있습니다. 일반적으로 루트에 정의된 모든 종속성의 단일 버전이 있습니다 . 때때로 Jest 및 Webpack과 같은 빌드 도구가 올바르게 작동하려면 래핑되어야 합니다. 해당 패키지의 빌드 도구를 수정해야 할 수 있으므로 이 저장소 스타일에 기존 패키지를 추가하는 것이 더 어렵습니다. 모든 도구 관련 결정이 이미 이루어졌기 때문에 새로운 프로젝트를 저장소에 추가하는 것은 간단합니다.
myorg/
├── packages/
└── is-even/
├── src/
| └── lib/
| | ├── is-even.spec.ts
| | ├── is-even.ts
| └── index.ts
├── project.json
├── package.json
├── ...
└── tsconfig.json
├── tools/
├── nx.json
├── package.json
├── README.md
└── tsconfig.base.json
Nx로부터 더 많은 도움을 원할 때. 확장성이 뛰어난 사전 구성된 설정을 제공하고 스캐폴딩 지원 및 자동화된 코드 마이그레이션을 제공하여 구성 부담을 덜어줍니다. 조직이 모노레포를 구매하고 확장하려는 경우 이 접근 방식을 선택합니다. 통합 저장소는 Nx가 더 많은 도움을 줄 수 있도록 일부 선택 사항을 제한할 수 있지만 장기적으로 더 나은 유지 관리성과 더 많은 가치를 제공합니다.
Standalone Applications
코드베이스를 모듈화하여 더 나은 확장성을 제공하는 기능을 위해 Nx를 사용합니다. 더 발전되고 더 유능한 Create-React-App 또는 Angular CLI로 생각하십시오
└─ myreactapp
├─ ...
├─ modules
│ ├─ products
│ │ ├─ ...
│ │ ├─ project.json
│ │ ├─ src
│ │ │ ├─ index.ts
│ │ │ └─ lib
│ │ │ ├─ products.spec.ts
│ │ │ └─ products.ts
│ │ ├─ tsconfig.json
│ │ ├─ tsconfig.lib.json
│ │ ├─ tsconfig.spec.json
│ │ └─ vite.config.ts
│ ├─ orders
│ │ ├─ ...
│ │ ├─ project.json
│ │ ├─ src
│ │ │ ├─ index.ts
│ │ │ └─ ...
│ │ └─ ...
│ └─ shared
│ └─ ui
│ ├─ ...
│ ├─ project.json
│ ├─ src
│ │ ├─ index.ts
│ │ └─ ...
│ └─ ...
├─ src
│ ├─ app
│ │ ├─ hello-world
│ │ │ ├─ hello-world.module.css
│ │ │ ├─ hello-world.spec.tsx
│ │ │ └─ hello-world.tsx
│ │ └─ ...
│ ├─ ...
│ └─ main.tsx
├─ ...
훌륭하게 구조화되고 모듈화될 수 있는 단일 프로젝트를 원하는 경우에 적합합니다. 모노레포를 살펴보는 것이 아니라 나중에 확장할 수 있는 옵션이 있는 경우 좋은 출발점이 됩니다.
TL;DR
상대적으로 규모가 크면 학습 곡선이 있더라도 Nx가 좋아보이고 Angular 를 우선 제공한다. 소규모 프로젝트에서는 TurboRepo 가 쉽고 Monorepo의 이점을 챙기기 좋고 Vercel/Meta 이해 관계, Next.js 를 Vercel 에서 서빙하기에 TurboRepo가 이성적으로는 좋아보인다.
둘다 사용해보신 팀원
작은 규모의 프로젝트에도 Nx를 사용해도 문제는 없을 것 같습니다. 무거운 감은 있지만요. 제공하는 범위 내에서 generator 를통해 여러 프레임워크/라이브러리 스타터를 곧바로 생성해내는 것도 편했구요(많은packages를 만들어야 할 필요가 없다면 크게 유용하다 느끼지 않을 수 있습니다)
Turbo든 Nx든 Lerna든 사실 실제 사용하는 입장에서 제공하는 기능의 차이가 크~게 있다고는 느끼지 못했습니다.
openapi가 빠르게 완료되어야 하는 프로젝트인 만큼 가볍고 빠르게 시작할 수 있으며 특히 실제 작업하는 개발자들이 익숙한 것이 좋다고 생각합니다~
Vercel에 너무 종속되는거 같다고 말했지만 실리콘벨리 최고의 개발자들이 만든 Next.js + TurboRepo + SWC 강력한 의견에 둘다 좋은 솔루션이고 모노레포를 가져가서 package based로 구성할 예정이라 TurboRepo로 결정
'software engineering > frontend' 카테고리의 다른 글
예측하지 못한 useCallback, react.memo 상황 (1) | 2023.10.29 |
---|---|
Type validation 뭐 써볼까? (0) | 2023.09.21 |
Style, CSS 뭐 써볼까? (0) | 2023.09.21 |
QueryClient 뭐 써볼까? (0) | 2023.09.21 |
React 18 매력적인 기능 (0) | 2023.05.01 |