notes
React에서 JavaScript heap out of memory — cross-env로 팀에 고정하기
FATAL ERROR: heap out of memory. 셸에만 NODE_OPTIONS를 넣지 말고, cross-env로 package.json에 고정해 Windows·Linux·CI까지 같이 가져가자.
무슨 일이었나
레거시를 버리고 TypeScript + React로 옮기던 때였다. 필요한 패키지를 잔뜩 깔고 start를 돌렸더니 바로 죽었다.
FATAL ERROR: Ineffective mark-compacts near heap limit
Allocation failed - JavaScript heap out of memory
처음엔 “내가 깐 라이브러리 중 하나가 망가졌나” 싶었다. 하나씩 넣었다 뺐다 하다 plotly.js를 넣는 순간 재현됐다. 그런데 plotly “버그”라기보다, 번들러(당시 Webpack)가 트랜스파일·번들하는 과정에서 Node(V8) 힙 한도를 넘긴 것에 가까웠다.
빠른 우회: NODE_OPTIONS
구글링하면 답이 단순하다. Node에 old space 상한을 키운다.
PowerShell
$env:NODE_OPTIONS="--max-old-space-size=8192"
bash / zsh
export NODE_OPTIONS="--max-old-space-size=8192"
8192는 MB 단위다 (대략 8GB). 노트북/CI 램에 맞게 4096·6144부터 올려도 된다.
여기까지는 “나 혼자 터미널에서”는 해결된다. 문제는 그다음이다.
- VS Code / 터미널을 다시 열면 설정이 사라진다.
- 메인에 “알아서
export하세요”를 올리는 건 팀에 무책임하다. - Windows 문법과 bash 문법이 달라서, OS별로 스크립트를 갈라 쓰기 쉽다.
팀에 고정: package.json + cross-env
셸에 붙이지 말고, 실행 스크립트에 환경을 박아 둔다. OS 차이를 흡수하려면 cross-env가 여전히 실용적이다.
npm i -D cross-env
{
"scripts": {
"start": "cross-env NODE_OPTIONS=--max-old-space-size=8192 webpack-dev-server --mode development",
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 webpack --mode production"
}
}
Vite / Next / CRA 계열도 원리는 같다. 앞에 cross-env NODE_OPTIONS=--max-old-space-size=8192만 붙이면 된다.
왜 cross-env인가
Unix만 쓰는 팀이면 NODE_OPTIONS=... command 문법이 통할 때도 있다. 그래도 Windows 동료·Git Bash·PowerShell이 섞이면 cross-env가 싸게 먹힌다.
해결 사다리 (어디까지 올릴까)
- 셸에만 — 재현 확인용.
- package.json + cross-env — 팀·CI 기본선.
- 근본 — 힙만 계속 키우면 러너/노트북에서 또 터진다.
- 무거운 차트·에디터는 동적
import() - 개발 빌드에서 불필요한 source map 끄기
- 모노레포면 패키지 단위로 빌드 쪼개기
- CI는 메모리 큰 러너 또는 Node 옵션을 워크플로에 명시
메모
increase-memory-limit같은 옛 글로벌 패치 패키지에 기대지 말자. 스크립트에NODE_OPTIONS를 직접 쓰는 편이 투명하다.- 에러 문구의
mark-compacts near heap limit는 GC가 한도 근처에서 허우적대다 실패한 신호다. “React 버그”로 단정하지 말 것. - Docker / GitHub Actions에서도 동일하게
NODE_OPTIONS또는cross-env가 들어간 script를 호출하면 된다. 로컬만 고치고 CI는 방치하면 같은 이슈가 파이프라인에서 재발한다. - 값을 무작정 16384로 올리면 스왑만 늘고 체감이 나빠질 수 있다. 재현되는 최소치부터 올리는 게 낫다.
체크리스트
- 로컬에서 OOM 재현 확인
-
cross-env+NODE_OPTIONS=--max-old-space-size=…를start/build에 반영 - Windows / macOS / Linux 중 최소 두 환경에서
npm start확인 - CI 워크플로가 같은 script를 쓰는지 확인
- 여전히 빡세면 무거운 의존성·번들 설정을 손본다 (한도만 키우지 않는다)
한 줄 요약
heap out of memory는 대개 “그 라이브러리 한 줄”이 아니라 빌드 프로세스 메모리 한도 문제다. 셸에 임시로 넣지 말고, cross-env로 npm script에 고정해 팀에 공유하자.