테마
Rush: Microsoft의 대규모 모노레포 관리 도구
Rush는 Microsoft가 개발한 모노레포 매니저로, pnpm 기반의 안전한 의존성 관리, 정책 관리, 변경 로그 자동화 등 대규모 팀과 프로덕션 환경에 특화된 기능을 제공한다.
학습 목표
- Rush의 특징과 다른 도구와의 차별점을 이해한다
- Rush의 핵심 기능(정책 관리, 변경 로그, 배포)을 설명할 수 있다
- pnpm 기반 의존성 관리와 팬텀 디펜던시 제거의 의미를 파악한다
- rush.json 설정의 주요 항목을 이해한다
- Rush의 워크플로(rush update, rush build, rushx)를 설명할 수 있다
1. Rush 소개
Rush는 스스로를 **"확장 가능한 웹용 모노레포 매니저"**라고 정의한다. 다른 도구들이 "빌드 시스템"을 표방하는 것과 달리, Rush는 명확하게 **"모노레포 매니저"**라는 관리 도구의 관점을 취한다.
Rush의 핵심 특성:
| 특성 | 설명 |
|---|---|
| 운영 주체 | Microsoft. 내부의 대규모 프로덕션 팀들이 실제로 사용 |
| 설계 철학 | 대규모 팀을 위한 거버넌스와 정책 관리에 초점 |
| 패키지 매니저 | pnpm을 기본으로 사용하여 팬텀 디펜던시를 근본적으로 차단 |
| 결정론적 빌드 | 설치와 빌드가 완전히 재현 가능하도록 보장 |
| 턴키 솔루션 | 설치, 링크, 빌드, 변경 로그, 배포까지 통합 오케스트레이션 |
주요 사용 기업:
Rush 홈페이지에 따르면, Microsoft의 다양한 제품팀에서 Rush를 사용하고 있다. Microsoft 외에도 일부 대규모 엔터프라이즈 환경에서 채택하고 있으나, 국내 레퍼런스는 매우 적은 편이다.
2. Rush의 핵심 기능
2.1 빌드 관리
Rush는 모노레포의 빌드를 네 가지 방식으로 최적화한다.
| 빌드 방식 | 설명 |
|---|---|
| 병렬 빌드 | CPU 코어를 최대한 활용하여 독립적인 프로젝트를 동시에 빌드한다 |
| 하위 집합 빌드 | rush build --to my-app으로 특정 프로젝트와 그 의존성만 빌드한다 |
| 증분 빌드 | 변경된 프로젝트와 영향받는 프로젝트만 다시 빌드한다 |
| 분산 빌드 | 여러 머신에 빌드 작업을 분산한다 (고급 설정 필요) |
bash
# 전체 프로젝트 빌드
rush build
# 특정 프로젝트와 그 의존성만 빌드
rush build --to my-app
# 변경된 프로젝트만 빌드 (증분)
rush build
# (git 커밋 이후, 변경 없으면 자동 스킵)중요: Rush의 증분 빌드와 캐싱은 git 커밋을 기반으로 동작한다. git이 초기화되지 않았거나 커밋이 없으면 캐싱 기능을 사용할 수 없다. 이 점은 다른 도구와 가장 크게 다른 특성이다.
2.2 정책 관리
Rush는 대규모 팀 환경에서 의존성과 코드 품질을 통제하기 위한 정책 관리 기능을 내장하고 있다.
의존성 승인 정책:
새로운 npm 패키지를 의존성에 추가하려면, 사전에 승인된 패키지 목록에 등록되어 있어야 한다. 이는 보안 취약점이 있는 패키지나 라이선스 문제가 있는 패키지가 무분별하게 추가되는 것을 방지한다.
일관된 버전 정책:
레포지토리 전체에서 특정 패키지의 버전을 통일하도록 강제할 수 있다. 예를 들어, 모든 프로젝트에서 React 18.2.0을 사용하도록 정책을 설정하면, 다른 버전을 사용하는 프로젝트가 있을 때 경고 또는 에러를 발생시킨다.
커밋 정책:
git 커밋 메시지 형식, 커밋 전 검증 등을 Rush 설정으로 관리할 수 있다.
2.3 pnpm 기반 의존성 관리
Rush는 pnpm을 기본 패키지 매니저로 사용한다. pnpm의 strict 모드를 활용하여 **팬텀 디펜던시(phantom dependency)**를 근본적으로 차단한다.
팬텀 디펜던시란?
npm이나 yarn의 호이스팅 방식에서는 직접 설치하지 않은 패키지도 node_modules에 끌려올라와 import할 수 있는 문제가 있다. 이것이 팬텀 디펜던시다. 해당 패키지가 다른 버전으로 업데이트되거나 제거되면 예상치 못한 오류가 발생한다.
Rush + pnpm 조합은 각 프로젝트가 명시적으로 선언한 의존성만 접근할 수 있도록 보장한다.
lockfile 탐색기:
Rush는 lockfile(pnpm-lock.yaml)의 내용을 시각화하여 버전 충돌을 분석하고 해결할 수 있는 탐색 도구를 제공한다.
2.4 변경 관리
Rush는 패키지의 변경 사항을 체계적으로 관리하는 워크플로를 내장하고 있다.
bash
# 변경 사항 기록 (PR 단위로 실행)
rush change
# 패키지 버전 증가
rush version --bump
# npm에 게시
rush publishrush change 명령을 실행하면:
- 변경된 프로젝트 목록을 표시한다.
- 각 프로젝트에 대해 변경 유형(major, minor, patch, none)을 선택한다.
- 변경 설명을 입력한다.
- JSON 형식의 변경 파일이
common/changes/디렉토리에 생성된다.
이 변경 파일들은 git에 커밋되며, 릴리스 시 자동으로 CHANGELOG에 반영된다. PR 리뷰 과정에서 변경 설명이 포함되므로, 릴리스 노트 작성 부담이 줄어든다.
3. Rush의 워크플로
Rush는 다른 도구들과 워크플로가 상당히 다르다. 모든 의존성 변경이 Rush를 통해 이루어져야 하며, rush update라는 명령이 핵심 역할을 한다.
3.1 핵심 명령어
| 명령어 | 용도 | 사용 시점 |
|---|---|---|
rush init | Rush 프로젝트 초기화. rush.json 및 기본 설정 파일 생성 | 프로젝트 최초 1회 |
rush update | 의존성 설치 및 갱신. 설정이나 의존성이 변경될 때마다 반드시 실행 | 설정 변경, 의존성 추가 후 |
rush add -p <패키지명> | 특정 프로젝트에 의존성 추가. --dev로 dev 의존성 | 패키지 추가 시 |
rush build | 전체 프로젝트 빌드. 의존 순서를 자동으로 계산 | 빌드 시 |
rushx <스크립트> | 현재 프로젝트의 package.json 스크립트 실행 | 프로젝트 디렉토리 내에서 |
rush change | 변경 사항 기록 (변경 로그용) | PR 작성 시 |
rush version --bump | 패키지 버전 증가 | 릴리스 시 |
rush publish | npm 게시 | 릴리스 시 |
3.2 rush update의 중요성
Rush에서 **가장 자주 실행하게 되는 명령은 rush update**다. rush.json에 프로젝트를 추가하거나, 의존성을 변경하거나, 설정을 수정할 때마다 반드시 실행해야 한다. rush update는:
- rush.json에 등록된 프로젝트들의 의존성을 확인한다.
- pnpm을 사용하여 의존성을 설치한다.
- 프로젝트 간 심볼릭 링크를 설정한다.
- lockfile을 갱신한다.
3.3 rushx vs rush build
| 명령어 | 범위 | 설명 |
|---|---|---|
rushx <script> | 현재 프로젝트만 | 현재 디렉토리의 package.json에 정의된 스크립트를 실행 |
rush build | 전체 프로젝트 | 모든 프로젝트의 build 스크립트를 의존 순서대로 실행 |
4. rush.json 설정
Rush 프로젝트의 핵심 설정 파일은 rush.json이다. 이 파일에 모든 프로젝트 정보와 런타임 설정이 정의된다.
json
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json",
"rushVersion": "5.112.0",
"pnpmVersion": "8.10.0",
"nodeSupportedVersionRange": ">=18.0.0 <21.0.0",
"projectFolderMinDepth": 2,
"projectFolderMaxDepth": 2,
"projects": [
{
"packageName": "my-utils",
"projectFolder": "projects/my-utils"
},
{
"packageName": "my-app",
"projectFolder": "projects/my-app",
"reviewCategory": "production"
}
]
}주요 설정 항목:
| 항목 | 설명 |
|---|---|
rushVersion | 사용할 Rush의 정확한 버전. git 브랜치에 따라 자동 설치 |
pnpmVersion | 사용할 pnpm의 정확한 버전 |
nodeSupportedVersionRange | 지원하는 Node.js 버전 범위 |
projects | 레포지토리에 포함된 모든 프로젝트 목록 |
projects[].packageName | 프로젝트의 npm 패키지 이름 |
projects[].projectFolder | 프로젝트의 디렉토리 경로 |
projects[].reviewCategory | 의존성 승인 정책의 카테고리 |
주의: Rush 프로젝트의 루트에는 package.json이 없다. 이것은 Rush가 다른 도구들과 구조적으로 다른 가장 큰 차이점이다. Rush 자체가 패키지 매니저를 관장하기 때문에, 루트 package.json 대신 rush.json이 그 역할을 한다.
5. Rush의 디렉토리 구조
Rush 프로젝트는 일반적인 모노레포와 구조가 다르다.
my-rush-repo/
rush.json # Rush 핵심 설정
common/
config/
rush/
command-line.json # 사용자 정의 명령어
common-versions.json # 공통 버전 정책
changes/ # rush change로 생성된 변경 기록
autoinstallers/ # 자동 설치 도구
projects/
my-utils/
package.json
src/
index.ts
my-app/
package.json
src/
pages/
index.tsxcommon/ 디렉토리에는 Rush가 자동으로 생성하고 관리하는 설정 파일들이 위치한다. common/config/rush/ 아래에 다양한 정책 파일들이 존재하며, 이를 통해 의존성 승인, 버전 정책, 커스텀 명령 등을 설정한다.
6. Microsoft 내부에서의 활용
Rush는 Microsoft 내부에서 대규모 프로덕션 모노레포를 유지 관리하는 전문 엔지니어들이 직접 구축한 도구다. Microsoft의 다양한 제품팀이 Rush를 사용하고 있으며, 이는 Rush의 설계에 직접적인 영향을 미쳤다.
대규모 환경에서의 강점:
- 수백 명의 개발자가 하나의 레포에서 작업할 때, 정책 관리로 코드 품질을 유지한다.
- 의존성 승인 프로세스로 보안 취약점이 있는 패키지의 유입을 차단한다.
- 결정론적 빌드로 "내 환경에서는 됩니다" 문제를 방지한다.
- pnpm의 strict 모드로 팬텀 디펜던시 문제를 근본적으로 차단한다.
Rush의 한계:
- 설정이 복잡하고 학습 곡선이 높다.
- 국내 레퍼런스가 거의 없어, 문제 발생 시 영문 문서에 의존해야 한다.
- 다른 도구에 비해 커뮤니티 규모가 작다.
- 일반적인 모노레포 구조와 다르므로, 기존 프로젝트 마이그레이션이 번거롭다.
7. 다른 도구와의 비교
| 비교 항목 | Rush | NX | TurboRepo |
|---|---|---|---|
| 핵심 철학 | 거버넌스, 정책 관리 | 스마트 빌드, 확장성 | 고성능, 단순함 |
| 패키지 매니저 | pnpm 전용 | npm/yarn/pnpm | npm/yarn/pnpm |
| 루트 package.json | 없음 | 있음 | 있음 |
| 설정 복잡도 | 높음 | 중간 | 낮음 |
| 의존성 승인 | 내장 | 없음 | 없음 |
| 버전 관리/배포 | 내장 | 없음 (Lerna 연동) | 없음 |
| 캐싱 전제조건 | git 커밋 필수 | 자동 | 자동 |
| 적합한 규모 | 대규모 (수백 패키지) | 중~대규모 | 소~대규모 |
핵심 정리
| 핵심 개념 | 요약 |
|---|---|
| Rush의 정체성 | 빌드 시스템이 아닌 모노레포 매니저. 설치부터 배포까지 통합 관리 |
| pnpm 기반 | 팬텀 디펜던시를 근본적으로 차단하고 결정론적 설치를 보장한다 |
| 정책 관리 | 의존성 승인, 일관된 버전 정책 등 대규모 팀을 위한 거버넌스 기능이 내장 |
| rush update | 설정이나 의존성이 변경될 때마다 반드시 실행해야 하는 핵심 명령어 |
| git 기반 캐싱 | 증분 빌드와 캐싱이 git 커밋을 전제로 동작한다 |
| 변경 관리 | rush change로 변경 내용을 기록하고, 릴리스 시 자동으로 CHANGELOG에 반영 |
| 국내 레퍼런스 | 매우 적음. 도입 시 영문 문서를 직접 읽어야 한다 |
다음 단계
이번 장에서는 Rush의 특징, 핵심 기능, 워크플로를 살펴보았다. 다음 장에서는 Vercel이 개발한 TurboRepo를 학습한다. TurboRepo는 Rush와 대조적으로 단순함과 고성능을 추구하는 빌드 시스템으로, 최근 빠르게 사용이 확산되고 있다.