pnpm 문제 였나?
해결 방법
⚠️ Next.js 버전별 차이점
Next.js 15.5+ 변경사항
// Next.js 15.5부터는 require-in-the-middle이 기본적으로 opt-out됨!
// 하지만 import-in-the-middle은 여전히 명시 필요
const nextConfig: NextConfig = {
serverExternalPackages: [
"import-in-the-middle", // 여전히 필요
// "require-in-the-middle", // 15.5+에서는 불필요 (기본 opt-out)
],
};
방법 1: next.config.ts 수정 (기본)
// next.config.ts
const nextConfig: NextConfig = {
serverExternalPackages: [
"import-in-the-middle",
// Next.js < 15.5인 경우에만 추가
...(process.env.NEXT_VERSION < '15.5' ? ["require-in-the-middle"] : []),
],
};
export default nextConfig;
방법 2: pnpm 사용 시 - .npmrc 설정 (권장)
pnpm의 엄격한 의존성 격리 때문에 발생하는 문제는 .npmrc 설정으로 해결:
# .npmrc
# pnpm의 엄격한 의존성 격리를 완화
# Sentry와 같은 instrumentation 도구가 간접 의존성에 접근할 수 있도록 허용
node-linker=hoisted
# 또는 부분적으로만 hoisting (더 안전)
public-hoist-pattern[]=*import-in-the-middle*
public-hoist-pattern[]=*require-in-the-middle*
pnpm의 의존성 격리 이해하기
# 기본 pnpm 구조 (격리됨)
node_modules/
├── .pnpm/
│ ├── @sentry+nextjs@8.0.0/
│ │ └── node_modules/
│ │ ├── @sentry/nextjs/ ← 실제 코드
│ │ └── import-in-the-middle/ ← 격리된 의존성
│ └── import-in-the-middle@1.0.0/
│ └── node_modules/
│ └── import-in-the-middle/
└── @sentry/ ← 심볼릭 링크
└── nextjs/
# hoisted 구조 (npm/yarn과 유사)
node_modules/
├── @sentry/
│ └── nextjs/
└── import-in-the-middle/ ← 최상위로 끌어올림
방법 3: 종합 해결책 (pnpm + Next.js 15.5+)
# .npmrc (프로젝트 루트)
# Sentry 관련 패키지만 선택적으로 hoisting
public-hoist-pattern[]=*import-in-the-middle*
public-hoist-pattern[]=*require-in-the-middle*
shamefully-hoist=false # 전체 hoisting은 하지 않음
// next.config.ts
const nextConfig: NextConfig = {
serverExternalPackages: [
"import-in-the-middle", // Next.js 15.5+에서도 필요
],
};
💡 해결 원리 이해하기
serverExternalPackages가 하는 일
// Before: Turbopack의 기본 동작
{
번들링_시도: true,
프로젝트_루트에서_찾기: true, // 실패! → 경고
런타임_동작: "Node.js가 알아서 찾음" // 정상 작동
}
// After: serverExternalPackages 설정 후
{
번들링_시도: false, // 아예 시도 안 함!
프로젝트_루트에서_찾기: false, // 확인할 필요 없음
런타임_동작: "Node.js가 알아서 찾음" // 정상 작동
}
pnpm vs npm/yarn 차이점
npm/yarn의 flat 구조
node_modules/
├── @sentry/nextjs/
├── import-in-the-middle/ ← 모든 패키지가 접근 가능
└── require-in-the-middle/
pnpm의 격리된 구조
node_modules/
├── .pnpm/ ← 실제 패키지들 (격리됨)
│ └── @sentry+nextjs@8.0.0/
│ └── node_modules/
│ ├── @sentry/nextjs/
│ └── import-in-the-middle/ ← Sentry만 접근 가능
└── @sentry/ ← 심볼릭 링크
└── nextjs/
pnpm의 장점:
- 디스크 공간 절약
- 의존성 충돌 방지
- 더 엄격한 의존성 관리
pnpm의 단점:
- Instrumentation 도구들이 간접 의존성 접근 어려움
- Turbopack과 충돌 가능성
Node.js 모듈 해석 알고리즘
// require('import-in-the-middle') 호출 시 Node.js의 탐색 순서:
[
'/your-project/node_modules/import-in-the-middle', // ❌ pnpm에서는 없음
'/your-project/node_modules/@sentry/.../node_modules/import-in-the-middle', // ❌ 심볼릭 링크
'/your-project/node_modules/.pnpm/.../import-in-the-middle', // ✅ 실제 위치
]
📎 참고 자료 업데이트
- Next.js serverExternalPackages 문서 - 15.5부터 require-in-the-middle 기본 opt-out
- Sentry pnpm 트러블슈팅
- pnpm의 node_modules 구조
- Turbopack 공식 문서
- Node.js 모듈 해석 알고리즘
💡 *Quick Fix *
npm/yarn 사용자
// next.config.ts에 추가
serverExternalPackages: ["문제의-패키지-이름"]
pnpm 사용자 (Sentry 등 instrumentation 도구)
# 1. .npmrc 파일 생성/수정
echo "public-hoist-pattern[]=*import-in-the-middle*" >> .npmrc
echo "public-hoist-pattern[]=*require-in-the-middle*" >> .npmrc
# 2. 의존성 재설치
rm -rf node_modules pnpm-lock.yaml
pnpm install
# 3. Next.js 15.5+ 사용 시
# next.config.ts에 import-in-the-middle만 추가 (require는 기본 opt-out)
버전별 체크
- Next.js < 15.5: 두 패키지 모두 serverExternalPackages에 추가
- Next.js ≥ 15.5: import-in-the-middle만 추가 (require-in-the-middle은 기본 제외됨)
- pnpm 사용 시: 추가로 .npmrc 설정 필요
'TIL' 카테고리의 다른 글
| [251123 TIL] Turbopack 간접 의존성 경고 상황 (0) | 2025.11.23 |
|---|---|
| [251123 TIL] OpenTelemetry? (with Next.js) (0) | 2025.11.23 |
| [251123 TIL] Next.js instrumentation.ts 정리 (0) | 2025.11.23 |
| [251102 TIL] PostgREST vs GraphQL(Hasura)기술 스택 비교 (0) | 2025.11.02 |
| [251031 TIL] naver 로그인 구현 with Supabase 3편 (1) | 2025.10.31 |