Logo wiki

개발 모드 (with Next.js)

January 31, 2026
2 min read
Table of Contents
index

Next.js 개발 중 발생한 에러

Next.js로 개발하던 중, 실제 경로에 있는 파일이 있음에도 존재하지 않는다는 에러(ENOENT)가 발생했다. alt text 에러 로그를 보면 분명 실제 경로가 맞았기 때문에 원인을 파악하기가 쉽지 않았다.
심지어 해당 파일에 브레이크포인트를 걸어도 디버깅이 잡히지 않았다.

문제의 원인은 mjml 라이브러리의 복잡한 의존성 구조 때문에 해당 경로의 파일이 번들링 되지 않았기 때문이었다.

따라서 실제 파일이 디스크에 존재하더라도, 번들에 포함되지 않으면 그 파일을 “없는 것”으로 인식한다.
이를 해결하기 위해 serverExternalPackages 옵션을 사용해 해당 패키지를 번들링 과정에서 제외하고,
Node.js의 require를 통해 의존성이 로드되도록 했다.

왜 원인을 번들링 문제라고 떠올리기 어려웠을까

next dev는 의존성 분석이 비교적 관대하고, 필요한 페이지만 ondemand로 컴파일한다.
이 과정에서 생성되는 .next/cache, .next/dev는 캐시나 중간 산출물,
HMR(Hot Module Replacement)용 데이터일 뿐, 프로덕션에서 실행 가능한 완성된 빌드 산출물은 아니다.

따라서 개발 모드에서 성공한다고 해서, 빌드에 의존성이 모두 들어갔다고 생각하면 안된다.

번들링이 필요한 이유

백엔드에서는 클라이언트가 필요한 자원(API)을 선택적으로 요청할 수 있다.
프론트엔드도 마찬가지로, 브라우저가 특정 페이지에 필요한 코드만 받을 수 있어야 한다.

하지만 개발 과정에서는 가독성과 유지보수를 위해 기능 단위로 파일을 잘게 나누는 경우가 많다.
번들링은 이때 필요한 의존성만 분석해서 묶어, 클라이언트에 전달하는 파일 수를 최소화하기위해 필요한 과정이다.

개발 모드, 운영 모드의 차이점 인지하기

개발 모드와 운영 모드는 동작 방식이 다르다.

예를 들어, React의 strict mode는 개발 모드에서 활성화되며,
생명주기와 사이드 이펙트를 검증하기 위해 일부 로직을 의도적으로 두 번 실행한다.

각 모드의 차이점을 이해하고 있어야, 한쪽에서만 발생한 에러를 맥락에 맞게 해석할 수 있을 것 같다.