배경: React 19 마이그레이션과 pnpm Catalogs pnpm workspace 기반의 모노레포 환경을 구축하여 프론트엔드 애플리케이션을 운영하고 있습니다. 기존에는 모노레포 내 여러 워크스페이스(앱)의 라이브러리 파편화를 막기 위해, 모든 의존성을 최상단(root)에서 일괄 관리해 왔습니다. 이에 따라 모든 앱이 동일하게 React 18 버전을 사용하고 있었으나, 최근 React 19로의 마이그레이션을 계획하게 되었습니다. 하지만 규모가 큰 모노레포 특성상 모든 앱을 한 […]
The post pnpm 모노레포에서 React 19 마이그레이션하기: 숨겨진 호이스팅 레이어가 만든 타입 충돌 트러블슈팅 first appeared on 우아한형제들 기술블로그. || 배경: React 19 마이그레이션과 pnpm Catalogs
pnpm workspace 기반의 모노레포 환경을 구축하여 프론트엔드 애플리케이션을 운영하고 있습니다. 기존에는 모노레포 내 여러 워크스페이스(앱)의 라이브러리 파편화를 막기 위해, 모든 의존성을 최상단(root)에서 일괄 관리해 왔습니다.
이에 따라 모든 앱이 동일하게 React 18 버전을 사용하고 있었으나, 최근 React 19로의 마이그레이션을 계획하게 되었습니다. 하지만 규모가 큰 모노레포 특성상 모든 앱을 한 번에 업데이트하는 것은 리스크가 컸습니다.
먼저 단계적인 마이그레이션을 진행하고 각 앱별로 의존성을 안전하게 격리하기 위해, pnpm의 catalogs 기능을 새롭게 도입했습니다.
pnpm Catalogs 도입: 앱별 의존성 격리
기존에 의존성을 최상단에서 일괄 관리했던 핵심적인 이유는 ‘버전 관리’ 때문이었습니다. 각 앱에서 개별적으로 패키지를 설치하다 보면 버전이 파편화될 위험이 컸기 때문입니다.
이러한 구조적 한계를 해결하기 위해 도입한 것이 바로 pnpm catalogs입니다. pnpm catalogs는 모노레포 워크스페이스 내에서 공통으로 사용할 패키지 버전을 한 곳에 정의하고, 여러 package.json에서 이를 참조할 수 있게 하는 기능입니다.
catalogs를 적용하여 최상단에서 관리하던 의존성을 각 워크스페이스에서 관리하도록 변경했습니다. 이를 통해 각 워크스페이스별로 독립적으로 버전을 관리하면서도, 모노레포 내의 라이브러리 버전 파편화를 방지할 수 있는 환경을 마련했습니다.
# pnpm-workspace.yaml
catalogs:
v1: # 기존 React 18 앱용
react: 18.2.0
react-dom: 18.2.0
"@types/react": 18.2.21
"@types/react-dom": 18.2.7
...
v2: # 신규 React 19 앱용
react: 19.2.4
react-dom: 19.2.4
"@types/react": 19.0.8
"@types/react-dom": 19.0.8
...
위와 같이 설정을 마치고, 업데이트 대상 앱에만 catalog:v2를 적용해 보았습니다.
// 기존 React 18을 유지하는 앱 - v1 참조
// apps/A/package.json
{
"name": "A",
"dependencies": {
"react": "catalog:v1",
"react-dom": "catalog:v1"
},
"devDependencies": {
"@types/react": "catalog:v1",
"@types/react-dom": "catalog:v1"
}
}
// React 19로 마이그레이션하는 앱 - v2 참조
// apps/B/package.jso