증상

로컬에서 npm run dev로 돌리면 멀쩡한데, Vercel이나 Netlify에 올리면 흰 화면이 뜨거나, "Module not found" 빌드 에러가 나거나, 데이터가 안 불러와지는 상황입니다. 바이브코딩으로 만든 앱을 처음 배포할 때 가장 많이 겪는 문제이고, 원인은 거의 정해져 있습니다.

핵심 이유는 하나입니다. 내 PC와 배포 서버는 서로 다른 "환경" 이라서, 내 컴퓨터에만 있던 설정·파일·주소가 배포 서버엔 없기 때문입니다. 아래 5가지를 순서대로 확인하면 대부분 잡힙니다.

1. 환경변수(env)를 배포 플랫폼에 안 넣었다 — 가장 흔함

내 PC의 .env 파일은 내 컴퓨터에만 있습니다. 보통 git에 안 올라가기 때문에 Vercel·Netlify는 그 파일의 존재를 모릅니다. 그래서 API 키·DB 주소 같은 값이 배포에선 전부 비어 있어 앱이 죽습니다.

해결 — Vercel:

  1. Vercel 대시보드 → 해당 프로젝트 클릭
  2. 상단 Settings → 왼쪽 Environment Variables
  3. Key(예: VITE_SUPABASE_URL)와 Value 입력 → Production·Preview·Development 모두 체크 → Save
  4. 상단 Deployments 탭 → 맨 위 배포 오른쪽 Redeploy

> 중요: Vercel은 "환경변수 변경은 기존 배포에 적용되지 않고 새 배포에만 적용"됩니다. 값을 넣었으면 반드시 재배포해야 반영됩니다.

해결 — Netlify:

  1. Netlify 대시보드 → 사이트 클릭
  2. Site configurationEnvironment variablesAdd a variable
  3. Key/Value 입력 → Save
  4. Deploys 탭 → Trigger deployClear cache and deploy site

주의: 브라우저에서 쓰는 값은 정해진 접두어가 필요

프론트엔드 코드(화면)에서 읽는 환경변수는 아래 접두어를 붙여야만 전달됩니다. 접두어가 없으면 값이 undefined로 나옵니다.

프레임워크접두어코드에서 읽는 법
Next.jsNEXT_PUBLIC_process.env.NEXT_PUBLIC_XXX
Vite (React·Vue)VITE_import.meta.env.VITE_XXX
Create React AppREACT_APP_process.env.REACT_APP_XXX

이 접두어가 붙은 값은 브라우저에 그대로 노출됩니다. 그래서 DB 비밀번호처럼 진짜 숨겨야 하는 값에는 접두어를 붙이면 안 됩니다.

2. 환경변수를 바꿨는데 재배포를 안 했다

환경변수 값은 빌드하는 순간 코드에 박혀서 굳습니다. Next.js·Vite·Create React App 모두 빌드 시점에 값이 인라인(하드코딩)됩니다. 그래서 대시보드에서 값을 고쳐도, 다시 빌드하기 전까지는 옛날 값 그대로입니다.

해결: 값을 바꾼 뒤 반드시 Redeploy(Vercel) / Trigger deploy(Netlify)를 한 번 더 눌러 새로 빌드하세요.

3. 파일 이름 대소문자가 안 맞는다 — "Module not found"

맥·윈도우는 Button.tsxbutton.tsx를 같은 파일로 취급합니다(대소문자 구분 안 함). 하지만 Vercel·Netlify의 빌드 서버는 리눅스라 대소문자를 엄격히 구분합니다. 그래서 실제 파일은 Button.tsx인데 코드에서 소문자로 import하면 로컬에선 통과, 배포에선 "Module not found" 에러가 납니다.

해결: import 경로의 대소문자를 실제 파일 이름과 글자 하나까지 똑같이 맞추세요. 폴더 이름도 마찬가지입니다.

js

// 실제 파일: src/components/Header.tsx

import Header from './components/Header'  // O 정상
import Header from './components/header'  // X 배포에서 Module not found

4. API 주소를 localhost로 하드코딩했다

코드에 http://localhost:3000 같은 주소를 직접 박아두면, 로컬에선 그게 내 서버라 되지만, 배포된 사이트에선 그 주소가 "방문자의 내 컴퓨터"를 가리켜 아무 응답도 못 받습니다.

해결: 주소를 환경변수로 빼고, 1번 방법으로 실제 배포 주소를 등록하세요.

js

// 잘못 — 로컬 주소가 코드에 박힘
fetch('http://localhost:3000/api/users')

// 고침 — 주소를 환경변수로 (Vite 기준)
fetch(`${import.meta.env.VITE_API_URL}/api/users`)

5. 로컬은 dev, 배포는 build — 빌드에서만 나는 에러

로컬에서 돌리는 npm run dev는 개발용이라 웬만한 오류를 넘어갑니다. 반면 배포는 npm run build(프로덕션 빌드)를 돌리는데, 여기서 타입 에러·import 에러가 훨씬 엄격하게 걸립니다.

해결: 올리기 전에 내 PC에서 배포와 똑같은 빌드를 직접 돌려 미리 잡으세요.

bash

npm run build

여기서 나오는 에러 메시지가 곧 배포가 실패하는 이유입니다. 이 에러를 로컬에서 다 없앤 뒤 올리면 됩니다.

마무리 체크리스트

  • .env의 값들을 Vercel·Netlify에도 똑같이 넣었나
  • 브라우저용 변수에 NEXT_PUBLIC_ / VITE_ / REACT_APP_ 접두어를 붙였나
  • 값을 넣거나 바꾼 뒤 재배포(Redeploy)를 눌렀나
  • import 경로 대소문자가 실제 파일명과 같나
  • 코드에 localhost 주소를 박아두지 않았나
  • npm run build가 내 PC에서 에러 없이 끝나나

이 6가지를 다 확인하면 "로컬에선 되는데 배포하면 안 되는" 문제는 거의 해결됩니다.