NX 모노레포 가이드라인
버전: v20.6
작성일: 2025-03-22
1. 개요
NX는 JavaScript/TypeScript 프로젝트를 위한 강력한 모노레포 도구입니다. 이 가이드라인은 DTA-WIDE 프로젝트에서 NX를 효과적으로 사용하기 위한 표준과 모범 사례를 제공합니다.
참고: 개발 환경 설정, 소프트웨어 설치, 환경 변수 설정 등 실제 개발 환경 구축에 관한 내용은 개발 환경 설정 가이드를 참조하세요.
2. NX 워크스페이스 구조
2.1 디렉터리 구조
dta-wide-mono/
├── apps/ # 애플리케이션 (배포 가능한 단위)
│ ├── dta-wide-api/ # 백엔드 API (NestJS)
│ └── web/ # 프론트엔드 앱 (React)
├── libs/ # 라이브러리 (재사용 가능한 코드)
│ ├── feature/ # 도메인별 기능 라이브러리
│ │ ├── auth/
│ │ ├── user/
│ │ └── ...
│ ├── core/ # 핵심 인프라 라이브러리
│ │ ├── database/
│ │ ├── config/
│ │ └── ...
│ └── shared/ # 공유 유틸리티 라이브러리
│ ├── dto/
│ ├── interfaces/
│ └── ...
├── tools/ # 개발 도구 및 스크립트
│ ├── generators/ # 커스텀 제너레이터
│ └── scripts/ # 유틸리티 스크립트
├── .nx/ # NX 캐시 및 설정
└── nx.json # NX 설정 파일
2.2 프로젝트 구성 원칙
- 애플리케이션(apps): 최종적으로 배포 가능한 단위
- 라이브러리(libs): 재사용 가능한 코드 모듈
- 도구(tools): 개발 도구 및 스크립트
3. 프로젝트 구성 규칙
3.1 네이밍 컨벤션
애플리케이션
- 짧고 명확한 이름 사용 (
dta-wide-api,web) - 하이픈(
-)으로 단어 구분
라이브러리
- 계층-기능 형식으로 구성
- 예:
feature-auth,core-database,shared-interfaces
태그 규칙
"tags": [
"scope:{core|feature|shared}",
"type:{api|ui|util|domain|...}",
"domain:{auth|user|...}"
]
3.2 의존성 규칙
- 단방향 의존성: core → shared → feature → app
- 순환 의존성 금지: 라이브러리 간 순환 참조 금지
- 의존성 경계:
core모듈은 다른 모듈에 의존하지 않음shared모듈은core모듈에만 의존feature모듈은core와shared에 의존 가능- 애플리케이션은 모든 모듈에 의존 가능
4. NX 명령어 체계
4.1 주요 명령어
프로젝트 생성 및 수정
# 워크스페이스 생성
npx create-nx-workspace@20.6.0 dta-wide-mono --preset=empty --packageManager=yarn
# NestJS 애플리케이션 생성
nx g @nx/nest:app --name dta-wide-api --directory=apps/dta-wide-api --tags=scope:api
# 라이브러리 생성
nx g @nx/nest:lib --name=feature-auth --directory=libs/feature/auth --tags=scope:feature,domain:auth
# Shared 라이브러리 생성
nx g @nx/nest:lib --name=shared-contracts-notification --directory=libs/shared/contracts-notification --tags=scope:shared,domain:contract
# 컨트롤러 생성
nx g @nx/nest:controller auth --project=feature-auth --directory=lib/controllers
참고: 이 명령어들의 실제 사용법과 로컬 개발 환경 설정 방법은 개발 환경 설정 가이드를 참조하세요.
빌드 및 실행
# 개발 서버 실행
nx serve dta-wide-api
# 빌드
nx build dta-wide-api
# 테스트
nx test feature-auth
# 린트
nx lint feature-auth
고급 기능
# 영향 받는 프로젝트만 실행
nx affected -t test
# 의존성 그래프 시각화
nx graph
# 여러 프로젝트에 대해 동시 실행
nx run-many -t build -p dta-wide-api feature-auth
4.2 NX v20.6의 새로운 기능
- Nx Agents: 빌드 및 테스트 실행 최적화
- 디스크 캐시 개선: 분산 환경에서의 캐시 효율성 향상
- 플러그인 API 개선: 확장성 강화
- 타겟 설정 개선: 더 유연한 실행 구성
5. 라이브러리 설계 가이드
5.1 라이브러리 유형
기능(Feature) 라이브러리
- 특정 도메인 기능 구현
- 특정 애플리케이션에 종속될 수 있음
- 예:
feature-auth,feature-user
유틸리티(Utility) 라이브러리
- 재사용 가능한 헬퍼 함수 및 유틸리티
- 애플리케이션에 독립적
- 예:
shared-utils
모델(Model) 라이브러리
- 데이터 모델 및 인터페이스 정의
- 여러 라이브러리에서 공유
- 예:
shared-dto,shared-interfaces
UI 라이브러리
- 재사용 가능한 UI 컴포넌트
- 프론트엔드 애플리케이션용
- 예:
shared-ui-components
5.2 라이브러리 경계 설정 원칙
- 단일 책임 원칙: 각 라이브러리는 하나의 책임 영역에 집중
- 변경 빈도에 따른 분리: 함께 변경되는 코드는 같은 라이브러리에 배치
- 팀 경계 고려: 팀 구조에 맞게 라이브러리 경계 설정
- 재사용성 평가: 재사용 패턴에 따라 라이브러리 분리
6. 모노레포 최적화 기법
6.1 빌드 최적화
- 증분 빌드 활용: 변경된 프로젝트만 빌드
- 병렬 빌드 설정: 동시에 여러 프로젝트 빌드
- 캐시 활용:
nx.json에서 캐시 설정 최적화
// nx.json
{
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"],
"parallel": 4
}
}
}
}
참고: 로컬 개발 환경에서의 구체적인 최적화 방법과 문제 해결에 대한 내용은 개발 환경 설정 가이드를 참조하세요.
6.2 CI/CD 최적화
- 영향 받는 프로젝트만 검증:
nx affected -t lint,test,build
- 이전 빌드 캐시 활용:
# GitHub Actions 예시
- name: Nx Cache
uses: actions/cache@v3
with:
path: .nx/cache
key: ${{ runner.os }}-nx-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-nx-
7. NX 설정 가이드
7.1 project.json
모든 프로젝트는 자체 project.json 파일을 가지며, 다음과 같은 표준 구성을 따릅니다:
{
"name": "feature-auth",
"sourceRoot": "libs/feature/auth/src",
"projectType": "library",
"tags": ["scope:feature", "domain:auth"],
"targets": {
"lint": { /* 린트 설정 */ },
"test": { /* 테스트 설정 */ },
"build": { /* 빌드 설정 */ }
},
"implicitDependencies": []
}
7.2 nx.json
루트 nx.json 파일은 모노레포 전체에 대한 설정을 포함합니다:
{
"extends": "nx/presets/npm.json",
"npmScope": "dta-wide",
"tasksRunnerOptions": { /* 실행기 옵션 */ },
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"inputs": ["production", "^production"]
},
"test": {
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"]
}
},
"workspaceLayout": {
"appsDir": "apps",
"libsDir": "libs"
}
}
8. 모범 사례 및 팁
8.1 코드 생성 활용
- 내장 제너레이터를 사용하여 일관된 코드 생성
- 커스텀 제너레이터를 개발하여 프로젝트 표준 적용
8.2 의존성 그래프 관리
- 정기적으로
nx graph검토 - 불필요한 의존성 제거 및 순환 의존성 방지
8.3 공통 코드 재사용
- 중복 코드는 공유 라이브러리로 추출
- 공유 인터페이스와 타입을 활용한 일관성 유지
8.4 캐시 최적화
- 클라우드 캐시 활용 (대규모 팀)
- 로컬 캐시 정기적 정리
9. NestJS와 NX 통합 팁
9.1 라이브러리 임포트 최적화
// 권장 임포트 방식
import { UserService } from '@dta-wide/feature/user';
// 비권장 상대 경로 임포트
import { UserService } from '../../../libs/feature/user/src/lib/user.service';
9.2 프로젝트 경계 유지
- 각 라이브러리의 public API는 index.ts에서만 내보내기
- 라이브러리 내부 구현 세부사항은 노출하지 않기
9.3 모듈 구성 최적화
// 도메인 모듈 구조
@Module({
imports: [CoreDatabaseModule],
controllers: [UserController],
providers: [UserService, UserRepository],
exports: [UserService]
})
export class UserModule {}
10. 문제 해결 및 디버깅
10.1 일반적인 문제 해결
- 캐시 관련 문제:
nx reset명령으로 캐시 초기화 - 의존성 문제:
nx graph로 의존성 검사 - 빌드 실패:
nx build --verbose로 상세 로그 확인
참고: 실제 개발 중 발생하는 구체적인 문제 해결 방법과 환경 설정 관련 문제는 개발 환경 설정 가이드에서 더 자세히 다루고 있습니다.
10.2 성능 문제 해결
- 느린 빌드: 캐시 설정 및 증분 빌드 확인
- CI/CD 최적화: 영향받는 프로젝트만 빌드/테스트
11. 버전 업그레이드 가이드
11.1 NX 버전 업그레이드 절차
# 최신 버전 확인
nx --version
# 마이그레이션 실행
nx migrate latest
# 패키지 업데이트
yarn
# 마이그레이션 적용
nx migrate --run-migrations
11.2 마이그레이션 고려사항
- 주요 변경 사항 체크: 공식 마이그레이션 가이드 참조
- 단계적 업그레이드: 메이저 버전 간 직접 업그레이드 지양
- 충분한 테스트: 업그레이드 후 모든 빌드/테스트 수행
12. 참고 자료
- NX 공식 문서
- NestJS 통합 가이드
- NX GitHub 저장소
- NX 모노레포 예제
- 개발 환경 설정 가이드 - DTA-WIDE 프로젝트의 실제 개발 환경 구축 가이드
13. 변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-03-22 | bok@weltcorp.com | 최초 작성 (NX v20.6 기준) |
| 0.1.1 | 2025-03-27 | bok@weltcorp.com | 개발 환경 설정 가이드(setup.md) 참조 추가 및 역할 명확화 |