서버 운영
Vite 개발 서버에서만 보이던 경로 오류를 base 설정으로 고친 기록
개발 환경에서는 정상인데 정적 배포 후 자산 경로가 깨졌던 원인을 base 설정과 브라우저 요청 주소로 좁힌 과정입니다.
처음에는 라우터 문제라고 생각했다
작은 React 화면을 Vite로 빌드한 뒤 정적 서버에 올렸더니 개발 서버에서는 보이던 아이콘과 CSS가 전부 사라졌다. 화면 HTML은 내려왔지만 브라우저 네트워크 탭에는 /assets/index-...js를 찾지 못했다는 404가 쌓였다. 저장소 아래 /demo/ 경로로 서비스하고 있었는데, 이 주소를 처음부터 확인하지 않은 것이 출발점이었다.
요청 주소를 먼저 비교했다
개발 서버와 배포 서버에서 같은 파일을 요청한다고 막연히 생각했지만 실제 주소가 달랐다. 배포 결과가 하위 경로에 들어간다면 Vite에 그 기준 경로를 알려야 한다.
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
base: '/demo/',
})
빌드 전에 base를 바꾸고, 결과물의 HTML에서 script와 stylesheet 주소가 /demo/assets/...로 시작하는지 확인했다. 여기서 끝내지 않고 실제 정적 서버의 fallback 규칙도 따로 점검했다. 경로 설정과 SPA 라우팅은 비슷하게 보이지만 서로 다른 문제였기 때문이다.
재현 명령을 고정했다
npm run build
python3 -m http.server 4173 --directory dist
curl -I http://127.0.0.1:4173/demo/assets/index-*.js
간단한 로컬 서버는 /demo/를 자동으로 처리하지 않을 수 있어, 최종 서버에서 사용하는 경로로 직접 접속해 확인했다. 해시 파일명은 매번 달라지므로 셸에서 별표가 그대로 전달되는 테스트는 믿지 않고 find dist/assets -type f로 실제 파일명을 확인했다.
다음 배포부터 보는 기준
- 서비스 루트가
/인지 하위 경로인지 먼저 적는다. - 빌드 산출물 HTML의 모든 정적 자산 주소를 확인한다.
- 브라우저 Network 탭에서 최초 404의 URL을 기록한다.
base수정과 라우터 fallback 수정을 한 커밋에 섞지 않는다.
이번 문제의 교훈은 설정값 자체보다 브라우저가 실제로 어느 URL을 요청했는지를 먼저 보는 것이었다. 다음에는 배포 미리보기에서 HTML과 자산 주소를 자동으로 검사하도록 CI에 한 줄짜리 검증을 추가할 예정이다.