wan의 개발일기
Submodule & Monorepo 개념 본문
들어가며
여러 저장소를 관리하는 방식에 대해 제대로 정리한 적이 없었다.
Submodule과 Monorepo는 서로 다른 문제를 해결하는 접근법이다. 개념과 사용 시점을 정리해둔다.
Git Submodule
Submodule이란?
하나의 Git 저장소 안에 다른 Git 저장소를 포함시키는 기능이다.
외부 라이브러리나 공통 모듈을 별도 저장소로 관리하면서 메인 프로젝트에서 참조할 때 유용하다.
main-project/
├── src/
├── .gitmodules
└── libs/
└── common-utils/ ← 별도 Git 저장소
Submodule 추가
# 저장소에 submodule 추가
git submodule add https://github.com/team/common-utils libs/common-utils
# .gitmodules 파일이 생성됨
cat .gitmodules
# [submodule "libs/common-utils"]
# path = libs/common-utils
# url = https://github.com/team/common-utils
Submodule 포함 저장소 clone
# submodule 포함해서 clone
git clone --recurse-submodules https://github.com/team/main-project
# 이미 clone한 경우 submodule 초기화
git submodule update --init --recursive
Submodule 업데이트
# 특정 submodule 업데이트
git submodule update --remote libs/common-utils
# 모든 submodule 업데이트
git submodule update --remote
# submodule 디렉토리로 이동해서 직접 작업도 가능
cd libs/common-utils
git switch main
git pull
cd ../..
git add libs/common-utils
git commit -m "chore: common-utils 버전 업데이트"
Submodule 제거
# 1. .gitmodules에서 항목 제거
git config -f .gitmodules --remove-section submodule.libs/common-utils
# 2. .git/config에서 항목 제거
git config --remove-section submodule.libs/common-utils
# 3. 스테이징에서 제거
git rm --cached libs/common-utils
# 4. 디렉토리 삭제
rm -rf libs/common-utils
rm -rf .git/modules/libs/common-utils
Submodule 주의사항
- submodule은 특정 커밋을 가리키는 포인터다. 브랜치를 추적하지 않는다
- 팀원이 clone 시 --recurse-submodules 옵션을 빠뜨리면 submodule이 비어있다
- submodule 내부 변경 후 메인 프로젝트에서도 커밋이 필요하다
Monorepo
Monorepo란?
여러 프로젝트(패키지)를 하나의 저장소에서 관리하는 방식이다. Submodule과는 반대로 저장소를 나누지 않고 하나로 합친다.
monorepo/
├── packages/
│ ├── web/ ← 프론트엔드
│ ├── api/ ← 백엔드
│ ├── mobile/ ← 모바일
│ └── shared/ ← 공통 유틸리티
├── package.json
└── turbo.json
Polyrepo vs Monorepo
| 항목 | Polyrepo | Monorepo |
|---|---|---|
| 저장소 수 | 프로젝트마다 분리 | 하나로 통합 |
| 코드 공유 | npm 패키지로 배포 | 직접 참조 |
| 변경 추적 | 저장소 간 추적 어려움 | 단일 커밋으로 추적 |
| CI/CD | 각자 독립적 | 통합 관리 가능 |
| 팀 규모 | 소규모, 독립적 팀 | 대규모, 긴밀한 협업 팀 |
대표 Monorepo 도구
npm/yarn workspaces
// package.json (루트)
{
"workspaces": [
"packages/*"
]
}
# 루트에서 모든 패키지 의존성 설치
npm install
# 특정 패키지에서 명령어 실행
npm run build --workspace=packages/web
Turborepo
빌드 캐싱과 병렬 실행을 지원하는 Monorepo 빌드 시스템이다.
# 프로젝트 생성
npx create-turbo@latest
# 전체 빌드 (변경된 패키지만 재빌드)
npx turbo build
# 전체 테스트
npx turbo test
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["build"]
}
}
}
패키지 간 참조
// packages/web/package.json
{
"dependencies": {
"@team/shared": "*" // 같은 저장소의 패키지 참조
}
}
Submodule vs Monorepo 선택 기준
외부 팀/오픈소스 저장소를 참조해야 한다 → Submodule
내부 여러 프로젝트를 함께 관리한다 → Monorepo
각 프로젝트가 완전히 독립적이다 → Polyrepo
정리
| 항목 | 설명 |
|---|---|
| Submodule | 저장소 안에 다른 저장소를 포함 |
--recurse-submodules |
submodule 포함 clone |
git submodule update --remote |
submodule 최신화 |
| Monorepo | 여러 프로젝트를 하나의 저장소로 관리 |
| npm workspaces | 기본 Monorepo 의존성 관리 |
| Turborepo | 빌드 캐싱, 병렬 실행 지원 |
'Git, Github > Github 심화' 카테고리의 다른 글
| GitHub Security (Secrets, Dependabot) (0) | 2026.05.04 |
|---|---|
| Git Hooks 활용하기 (0) | 2026.05.03 |
| 오픈소스 기여하기 (fork, PR) (0) | 2026.05.03 |
| GitHub Pages로 정적 사이트 배포 (0) | 2026.05.03 |
| GitHub Issues & Projects로 일감 관리 (0) | 2026.05.03 |