모노레포를 도입한 이유는 단순했다.
1. 웹은 Next.js로, 모바일은 React-Native로 만들기
2. 공통된 API 요청으로 UI 컴포넌트를 재사용해보고 싶다.
3. 배포 스크립트, ESLint, TypeScript의 설정 등을 한 번에 관리하고 싶다.
4. 현업에서 모노레포를 사용하는 경우도 있기 때문에 경험해보고 싶다.
그래서 아래와 같은 구조로 프로젝트를 세팅했다.
CheckBiz/
|----- apps/
| |----- web/ # Next.js
| |----- mobile/ # React Native
|----- packages/
|----- ui/ # 공유 UI 컴포넌트
|----- api/ # 공통 API 로직
나는 yarn workspace를 사용했고
이전에 yarn을 사용하면서 경험해보지 못한 문제를 경험하기 시작했다.
설치, 삭제... 그리고 설치, 삭제의 무한 굴레...
공식문서를 찾아보았다.
왜 자꾸 안되는걸까?
React Native 0.79.1은 새로운 Gradle plugin 방식 (com.facebook.react)을 사용한다.
공식 문서에 따르면 다음처럼 설정하라고 한다
settings.gradle.kts
pluginManagement {
includeBuild("../node_modules/@react-native/gradle-plugin")
}
하지만 나는 yarn workspace를 사용하고 있었고
아래와 같은 문제가 계속 발생했다.
node_modules/@react-native/gradle-plugin => 이게 계속루트에 설치됨
apps/mobile/node_modules/@react-native/gradle-plugin => 이건 설치를 계속 해도 계속 없음
Gradle은 includeBuild("상대경로")로 명시한 경로가 실제 존재하지 않으면 바로 실패한다.
즉, apps/mobile 기준의 상대경로에 해당 플러그인이 정확히 설치되어 있어야만 작동한다.
루트에 설치된 플러그인은 Gradle이 사용되어야하는 mobile에는 아예 설치가 되어있지 않고 그로 인해서 애초에 경로가 맞지 않기 때문에 무조건 실패한다는 의미다.
😵 여기서 헤맨 포인트
package.json의 workspace 설정이 정확히 어떻게 작동하는지 모른 상태에서
apps/mobile이 아닌 루트에서 자꾸 @react-native/gradle-plugin을 설치했다.
"workspaces": [
"apps/web",
"apps/mobile",
"packages/*"
]
이렇게 되어 있는 상태에서 루트에서 yarn add를 실행하면 해당 패키지가 workspace 내 apps/mobile로 연결되지 않고 루트에 깔리는 문제가 발생한다.
루트에서 yarn이 설치나 제거 시 이 경로 내의 디렉토리만 workspace로 인식해서 관리하겠다는 의미다.
하지만 중요한 점은 다음과 같다
즉, 루트에서 설치한 것은 apps/mobile 하위에서는 상대 경로 기준에 맞지 않기 때문에 Gradle이 찾지 못한다.
따라서 루트의 package.json에서 workspace 내용들을 지우고 원하는 경로에 gradle-plugin을 설치한 다음에 다시 package.json에 workspace를 기존처럼 복구했다.
루트에서 제거
cd /
yarn remove @react-native/gradle-plugin -Wapps/mobile로 이동해서 설치
cd apps/mobile
yarn add -D @react-native/gradle-plugin
이후 다시 gradlew clean 실행 → 플러그인 인식 성공
workspace 설정 목적
여러 패키지 디렉토리를 하나의 프로젝트로 묶고, 의존성을 효율적으로 관리하기 위해서
workspaces는 기본적으로 루트가 패키지를 컨트롤하는 관리자이기 때문.
yarn add를 루트에서 실행하면 루트가 그 패키지를 자기 자신의 의존성으로 등록하는 것이고
apps/mobile 디렉토리에서 yarn add를 실행해야 그걸 모바일 프로젝트 전용으로 인식함
즉,
workspaces는 공유/재사용/관리의 범위를 지정하는 것이지 자동으로 하위 프로젝트에 설치해주는 건 아님
Could not find com.android.tools.build:gradle:8.8.2
Gradle은 google() 레포에서만 Android 플러그인을 찾는다.
하지만 나는 settings.gradle.kts에 이걸 안 넣고 있었던 것!
pluginManagement {
repositories {
google() //이걸 빼먹었음!
mavenCentral()
}
includeBuild("../node_modules/@react-native/gradle-plugin")
}
모노레포에서 React Native와 Next.js를 함께 쓰는 건 분명 어렵다.
특히 Gradle과 Android 설정은 "당연하게 되겠지"라고 생각하면 무조건 막힌다.
하지만 이번 경험으로 확실히 얻은 점이 있다!
거의 일주일간 설치-삭제-빌드 반복하면서... 아 난 개발자가 아닌가 보다, 모노레포 포기하고 그냥 앱으로만 만들까? 이런 오만 생각에 사로잡혔다...
앞으로 개발자의 길을 가면서 온갖 문제들에 봉착하게 될텐데 이런건 사소한 문제지 하는 생각도 들었던 기간이었다.
그럼에도 불구하고 깨달을 수 있었던 건 이게 바로 개발의 묘미지!
막혔을 때 이유를 파고들고 그동안의 프로젝트에서는 막연하게 실행이 되니까 원리 이해없이 지나갔던 문제들도 이번 기회를 통해 이해할 수 있게 되었고 고칠 수 있게 된 점이 있어서 기쁘다.
다음번에는 이 구조 위에 테스트, 배포 파이프라인, CI/CD까지 이어서 작성할 계획이다.
나처럼 이런 문제에 부딪힌 사람들, 앱+웹 같이 운영하고 싶은 사람들에게 도움이 되었으면 함!