wan의 개발일기

Submodule & Monorepo 개념 본문

Git, Github/Github 심화

Submodule & Monorepo 개념

wan_ 2026. 5. 4. 22:59

들어가며

여러 저장소를 관리하는 방식에 대해 제대로 정리한 적이 없었다.
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 빌드 캐싱, 병렬 실행 지원