Conversation
config 가 없을 때만 만들고 있으면 경고만 남겼는데, create-next-app 은 스캐폴딩 때
next.config.mjs 를 항상 만든다. 그래서 생성 분기는 현실에서 거의 발화하지 않고
커밋된 config 가 유일한 진실이 된다.
그 config 에는 output: 'export' 가 없다. next build 는 .next 만 만들고 ./out 은
생기지 않으므로 publish 스텝이 그 디렉터리를 찾다 실패한다 — 자산 404 이전에 배포
자체가 끝까지 가지 못한다.
basePath 도 커밋된 값이 알 수 없는 값이다. 커스텀 도메인이 붙으면 '/', 아니면
'/{repo}' 여야 하는데 이건 배포 시점에만 정해진다.
덮어쓰지 않고 감싼다. 사용자의 config 를 옆으로 옮긴 뒤 그것을 불러와 우리가
소유하는 세 필드만 얹은 config 를 새로 쓴다. 사용자가 적은 다른 설정(redirects,
env, webpack 등)은 그대로 살아남는다. 파싱하지 않으므로 형식(JS/MJS/TS)에 기대지
않는다 — Next 자신이 읽게 두고 결과 객체에만 손댄다.
우리가 세 필드를 소유하는 근거는 각각 다르다. output 과 images.unoptimized 는
GitHub Pages 가 정적 호스팅이라는 사실에서, basePath 는 배포 URL 에서 나온다.
셋 다 사용자가 정할 수 있는 값이 아니다.
실측(2026-08-25, 워크플로 셸 로직을 그대로 실행):
ESM(.mjs) 사용자의 reactStrictMode·env 유지 + 세 필드 적용
CJS(.js) images.formats 유지한 채 unoptimized 추가, 커스텀 도메인이면 basePath ''
함수형 module.exports = () => ({...}) 도 평가해 병합
basePath 는 trailing slash 가 없어야 해서 QEPLOY_BASE_PATH 를 따로 넘긴다.
기존 BASE_PATH/PUBLIC_URL 은 slash 를 포함한다(Vite --base, CRA homepage 가 그
형태를 요구한다).
TypeScript 는 '.ts' 확장자 import 를 허용하지 않고 ESM 은 확장자를 반드시 요구하므로
import 경로를 확장자에 따라 가른다.
범위는 Next.js 로 한정했다. 우리 CODE 프롬프트가 제시하는 넷(Vite+React, CRA, Vue,
Next.js) 중 깨지는 것은 Next.js 하나다 — 나머지는 vite build --base 나 homepage
덮어쓰기로 이미 배포 시점 값이 이긴다. gatsby/sveltekit/astro/nuxt/vue-cli 는
사용자가 기존 저장소를 연결할 때만 등장하므로 별도 단위로 남긴다(#116).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(deploy): Next.js 배포에서 커밋된 config 가 이겨 산출물이 나오지 않던 문제
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
develop → main. #172 하나뿐이고 마이그레이션 변경은 없다.
무엇을 고치나
create-next-app은 스캐폴딩 때next.config.mjs를 항상 만든다. 그런데 배포 워크플로는 config 가 없을 때만 만들고 있으면 경고만 남겼다. 그래서 생성 분기는 현실에서 거의 발화하지 않고 커밋된 config 가 유일한 진실이 된다.그 config 에는
output: 'export'가 없다.next build는.next만 만들고./out은 생기지 않으므로 publish 스텝이 그 디렉터리를 찾다 실패한다 — 이슈 제목의 "자산 404" 이전에 배포 자체가 끝까지 가지 못한다.해결 — 덮어쓰지 않고 감싼다
사용자의 config 를 지우지 않고 옆으로 옮긴 뒤, 그것을 불러와 우리가 소유하는 세 필드만 얹는다. 파싱하지 않으므로 형식(JS/MJS/TS)이나 내용에 기대지 않고, 사용자가 적은 redirects·env·webpack 설정은 그대로 살아남는다.
output과images.unoptimized는 GitHub Pages 가 정적 호스팅이라는 사실에서,basePath는 배포 URL 에서 나온다 — 셋 다 사용자가 정할 수 있는 값이 아니다.실측 (워크플로 셸 로직을 그대로 실행)
.mjs(reactStrictMode,env).js(images.formats), 커스텀 도메인formats유지 +unoptimized,basePath: ""() => ({...})basePath는 trailing slash 가 없어야 해서QEPLOY_BASE_PATH를 따로 넘긴다(기존BASE_PATH/PUBLIC_URL은 slash 포함). TypeScript 는.ts확장자 import 를 허용하지 않아 import 경로를 확장자에 따라 가른다.범위
Next.js 로 한정했다. CODE 프롬프트가 제시하는 넷(Vite+React, CRA, Vue, Next.js) 중 깨지는 것은 이것 하나이고, 나머지는
vite build --base나homepage덮어쓰기로 이미 배포 시점 값이 이긴다. gatsby·sveltekit·astro·nuxt·vue-cli 는 기존 저장소 연결에서만 등장하므로 #116 을 열어둔다.검증
./gradlew test전체 통과bc37c6a) 및 기동 확인기존 저장소는 다음 배포부터 적용된다 — 워크플로 파일은 배포 때마다
ensureWorkflow가 다시 쓴다.🤖 Generated with Claude Code