2026-06-08

빌드는 통과, 화면만 죽는 버그 — React 19 런타임

가장 오래 붙잡은 버그는 정황이 이상했다. npm run build는 멀쩡히 통과하고, 개발 서버도 200을 돌려주는데, 정작 브라우저 화면만 새하얗게 죽었다.
콘솔을 열어보니 한 줄이 떠 있었다.

Cannot read properties of undefined (reading 'ReactCurrentOwner')

처음엔 내 컴포넌트를 의심했지만 거기엔 문제가 없었다.
원인은 한참 아래, 런타임에 있었다.

핵심은 package.json이 거짓말을 한다는 것이다.
의존성에는 react 18이 적혀 있었지만, Next 16의 App Router는 그 버전과 무관하게 자체 번들된(vendored) React 19 런타임으로 클라이언트 컴포넌트를 실행한다.
내가 설치했다고 믿은 React와 실제로 브라우저에서 도는 React가 달랐다.

그 틈에서 R3F v8이 걸려 넘어졌다.
v8은 React 19에서 제거된 내부 API(ReactCurrentOwner 같은)에 의존하는데 19 런타임엔 그게 없다.
그래서 모듈을 평가하는 시점부터 undefined를 읽으며 크래시했다.
빌드는 타입과 번들만 보니 멀쩡, 실행은 런타임 API가 없으니 즉사였다.

해결은 깔끔했다.
스택을 React 19에 맞춰 일괄 올렸다 — react 19, fiber 9, drei 10, postprocessing 3.
내 게임 코드는 한 줄도 안 고쳤다.
버전 정렬만으로 화면이 살아났다.

교훈은 분명하다.
빌드 통과와 서버 200은 "동작한다"의 증거가 못 된다.
런타임 호환성은 브라우저 콘솔까지 직접 봐야 안다.

다음 편부터는 손맛을 만든 아케이드 물리로 넘어간다.
먼저 이동과 점프다.

다음 편: 아케이드 물리 — 이동과 점프 →