Vite 8 완전 정복: 실무자가 알려주는 핵심 설정 8가지 (빌드 속도 10배 비결까지!)
2026. 5. 26.
Vite 8 완전 정복: 실무자가 알려주는 핵심 설정 8가지 (빌드 속도 10배 비결까지!)
지난주 Vueconf US에 다녀왔습니다. 매년 꼭 참석하려 노력하는 제가 정말 좋아하는 컨퍼런스 중 하나죠. 이번 컨퍼런스에서 에반 유(Evan You)는 Vue와 툴링의 미래에 대해 강연했는데, 도중에 최근 출시된 Vite 8의 새로운 기능들을 언급했을 때 정말 깜짝 놀랐습니다. 수백만 다운로드를 기록하며 엄청나게 성장했는데도, 정작 많은 개발자들이 최신 기능을 잘 모르고 있다는 점이 인상 깊었어요. 에반이 청중에게 Vite 8을 써본 사람 손들어보라고 했을 때, 겨우 몇 명만 손을 들더라고요! 그래서 집으로 돌아오자마자 이 글을 쓰고, Vite 8과 함께 꼭 시도해봐야 할 몇 가지 설정에 대한 영상을 만들기로 결심했습니다.
Vite 8은 최근 출시되면서 Vite 2 이후 가장 큰 아키텍처 변화를 가져왔습니다. 특히 주목할 만한 변화 중 하나는 Rust 기반 번들러인 '롤다운(Rolldown)' 도입인데, 덕분에 빌드 속도가 무려 10~30배나 빨라졌다고 합니다. 물론 Vite를 별다른 설정 없이 '제로 설정'으로만 써왔어도 좋습니다. 기본 설정도 훌륭하니까요. 하지만 오늘 제가 소개할 몇 가지 옵션들은 한 번 알아두면 모든 프로젝트에서 계속 찾게 될 강력한 기능들입니다.
이 글에서는 꼭 알아야 할 Vite 설정 8가지를 다룹니다. 그중 2가지는 Vite 8에 새로 추가된 것이고, 나머지 6가지는 이미 존재했지만 많은 분들이 놓치기 쉬웠던 옵션들이죠. 이 모든 설정은 여러분의 vite.config.ts 파일에서 적용할 수 있습니다.
이 포스팅은 AI 기반 IDE인 Kiro를 활용해 작성했습니다. 특히 첫 번째 섹션의 forwardConsole 옵션은 Kiro 같은 AI 코딩 에이전트에 직접적으로 도움이 됩니다.
더 생생한 데모와 함께 이 모든 내용을 다룬 영상도 만들었습니다. 읽는 것보다 보는 것을 선호하신다면 아래 영상을 확인해보세요!
{% youtube WbIz38_54KM %}
준비물
- Node.js 20.19+ 또는 22.12+ (Vite 8 요구사항)
- Vite 프로젝트 (어떤 프레임워크든 상관없습니다)
Vite 8으로 업그레이드하려면:
npm install vite@latest
핵심 설정 엿보기
1. server.forwardConsole
Vite 8에 새로 추가된 기능입니다. 이 옵션을 활성화하면 브라우저 콘솔 오류와 경고가 개발자 도구(DevTools)에만 나타나는 것이 아니라, Vite 터미널에도 함께 표시됩니다.
export default defineConfig({
server: {
forwardConsole: true,
},
})
브라우저 화면을 직접 볼 수 없는 AI 코딩 에이전트와 함께 작업할 때나, 단순히 개발자 도구로 전환하는 대신 터미널에 시선을 고정하고 싶을 때 유용합니다. Vite는 @vercel/detect-agent를 통해 AI 코딩 에이전트를 감지하면 자동으로 이 기능을 활성화하지만, 그렇지 않은 경우 기본값은 false입니다.
좀 더 세부적으로 설정할 수도 있습니다:
server: {
forwardConsole: {
unhandledErrors: true, // 처리되지 않은 오류를 전달
logLevels: ['warn', 'error'], // 특정 로그 레벨만 전달
},
}
출력되는 메시지에는 소스맵(source-mapped) 스택 트레이스가 포함되어 있어, 컴파일된 결과물이 아닌 실제 TypeScript 소스 코드의 라인 번호를 확인할 수 있습니다. 제가 최근 AI 페어 프로그래밍을 할 때 이 기능을 켜봤는데, 브라우저와 터미널을 번갈아 볼 필요 없이 한눈에 오류를 확인할 수 있어서 생산성이 훨씬 올라갔습니다.
2. resolve.tsconfigPaths
역시 Vite 8에 새로 추가된 기능입니다. 이전에는 TypeScript 경로 별칭(path alias)을 사용하려면 vite-tsconfig-paths 플러그인을 별도로 설치해야 했지만, 이제는 빌트인으로 내장되어 개발 서버와 빌드 모두에서 작동합니다.
export default defineConfig({
resolve: {
tsconfigPaths: true,
},
})
여기서 많은 분들이 실수하는 한 가지 설정 오류가 있습니다: paths는 tsconfig.json 파일의 최상위 레벨이 아닌 compilerOptions 내부에 정의되어야 합니다. 수동으로 편집할 때 쉽게 틀릴 수 있는 부분이죠.
// 잘못된 설정 — paths가 최상위 레벨에 있어 Vite에 의해 무시됨
{
"files": [],
"paths": { "@/*": ["./src/*"] },
"references": [{ "path": "./tsconfig.app.json" }]
}
// 올바른 설정 — paths가 compilerOptions 내부에 정의됨
{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }],
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"]
}
}
}
이 옵션은 약간의 성능 비용이 발생할 수 있어 기본값이 아닌 옵트인(opt-in) 방식으로 제공됩니다. TypeScript 팀 또한 paths 설정은 다른 도구에 의해 처리되는 매핑 정보를 TypeScript에 알려주는 용도이지, 코드 출력 동작을 변경하는 용도가 아니라고 명시하고 있습니다. 그래도 저는 충분히 시도해 볼 가치가 있다고 생각합니다.
실무에서 타입스크립트 기반 프로젝트를 진행하다 보면 경로 별칭(path alias) 설정이 늘 번거로웠는데, 이제 Vite 8부터 빌트인으로 지원되니 정말 편리합니다. 특히 tsconfig.json에서 paths 설정을 compilerOptions 안에 넣는 실수는 제가 코드 리뷰할 때도 종종 발견하는 부분이니 꼭 유의하세요!
resolve.alias vs resolve.tsconfigPaths: 어떤 것을 사용해야 할까요?
| 구분 | resolve.alias | resolve.tsconfigPaths |
|---|---|---|
| 설정 위치 | vite.config.ts | tsconfig.json |
| 순수 JS 프로젝트 | ✅ | ❌ |
| 단일 진실 공급원 | ❌ | ✅ |
| Vite 8 필요 | ❌ | ✅ (빌트인) |
| 성능 비용 | 없음 | 약간 있음 |
별칭을 한곳에서 정의하고 싶고 이미 TypeScript를 사용하고 있다면 tsconfigPaths를 사용하세요. 순수 JS 프로젝트, 모노레포, 또는 TypeScript 설정과 독립적인 별칭을 원한다면 alias를 사용하면 됩니다.
3. server.proxy
이 옵션을 사용하는 개발자를 많이 보지 못했습니다. 프록시는 단순히 CORS 문제를 해결하는 것 이상의 의미를 가집니다. 바로 개발 환경을 프로덕션 환경과 유사하게 만드는 데 목적이 있죠.
프로덕션 환경에서는 보통 프론트엔드와 API가 동일한 도메인에 배포됩니다. 동일한 원본(origin)을 가질 수 있으므로 CORS가 필요 없는 경우가 많습니다. 예를 들어, 개발 시에는 프론트엔드가 localhost:5173에서 실행되고 백엔드는 localhost:8080에서 실행될 수 있습니다. 이렇게 포트가 다르면 서로 다른 원본이 되므로 CORS 오류가 발생하죠. 프록시를 사용하면 이 문제를 해결할 수 있습니다.
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8080', // 요청을 보낼 백엔드 서버 주소
changeOrigin: true, // 대상 서버의 호스트 헤더를 변경 (CORS 문제 방지)
rewrite: (path) => path.replace(/^\/api/, ''), // /api 프리픽스 제거
},
},
},
})
위 설정은 /api/*로 시작하는 모든 요청을 http://localhost:8080/*으로 전달합니다. 브라우저는 localhost:5173으로만 요청하는 것으로 인식하므로, 교차 출처(cross-origin) 요청이 발생하지 않고 CORS 오류도 생기지 않습니다.
이 옵션을 사용해야 하는 몇 가지 다른 이유:
- 팀원의 서비스나 타사 API를 사용하는데
localhost가 CORS 설정에 추가되어 있지 않나요? 그들의 서버를 변경할 수는 없지만, Vite 프록시를 통해 우회할 수 있습니다. - 백엔드에
Access-Control-Allow-Origin: localhost:5173을 추가하는 것은 개발 환경에 대한 고려사항이 프로덕션 설정에 스며드는 것을 의미합니다. 프록시는 이를 완전히 분리시킬 수 있습니다. - 프록시의
configure콜백에서 외부 서비스에 대한 인증 헤더를 주입하여, 브라우저 번들에서 해당 정보를 숨길 수 있습니다. 물론 이는 개발 전용이며, 프로덕션에서는 서버 측에서 인증을 처리해야 합니다.
changeOrigin: true는 요청이 대상 호스트에서 온 것처럼 보이게 하여 일부 백엔드에서 필요로 합니다. rewrite는 /api 접두사를 제거한 후 요청을 전달합니다. 프론트엔드와 백엔드 개발 서버 포트가 다를 때 CORS 에러는 정말 흔한 문제죠. server.proxy는 이런 상황에서 임시방편이 아니라, 프로덕션 환경과의 일관성을 유지하면서 개발을 매끄럽게 하는 스마트한 해결책이라고 생각합니다.
4. server.hmr.overlay
기본적으로 Vite는 서버 오류가 발생하면 전체 화면을 덮는 빨간색 오버레이를 표시합니다. 런타임 오류, HMR(Hot Module Replacement) 실패, 트랜스폼 오류 등이 모두 이 오버레이를 트리거합니다. 편집 중에 이 오버레이가 방해가 된다면 끌 수 있습니다.
export default defineConfig({
server: {
hmr: {
overlay: false, // HMR 오류 오버레이 비활성화
},
},
})
오류는 여전히 터미널과 브라우저 콘솔에 나타납니다. UI 작업에 집중하고 있는데 오버레이가 계속해서 편집 중인 컴포넌트를 가릴 때 이 옵션을 끄면 좋습니다. 저는 UI 작업 시에 이 빨간 오버레이가 화면을 가리는 게 꽤 방해가 되더라고요. overlay: false로 설정하고 나니 훨씬 깔끔하게 작업할 수 있어서 애용하고 있습니다. 물론 팀원 중에는 즉각적인 시각적 피드백을 선호하는 분들도 있으니, 개인의 작업 스타일에 맞춰 조절하는 게 좋겠죠.
5. resolve.alias
tsconfigPaths를 선호하긴 하지만, 때로는 resolve.alias를 사용해야 할 때도 있습니다. 이 옵션은 tsconfig.json을 전혀 건드리지 않고도 가져오기(import) 단축 경로를 설정하는 명시적인 방법입니다. JS 프로젝트, 모노레포, 또는 TypeScript의 경로 해석과 무관하게 별칭을 설정하고 싶을 때 아주 유용합니다.
import path from 'path' // Node.js 환경에서 path 모듈 필요
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
},
})
path.resolve (또는 ESM 환경에서는 fileURLToPath)를 사용하여 올바른 절대 경로를 지정해야 합니다. '/src'와 같은 단순한 문자열을 전달하면 대부분의 시스템에서 파일 시스템 루트로 해석되므로, 프로젝트 루트가 아닌 다른 곳을 가리키게 될 수 있습니다.
tsconfigPaths가 타입스크립트 프로젝트에서 '정답' 같은 느낌이라면, resolve.alias는 유연성이 필요한 상황에서 빛을 발합니다. 특히 레거시 프로젝트를 마이그레이션하거나, tsconfig.json에 직접 접근하기 어려운 모노레포 환경에서 이 친구가 없으면 답답할 때가 많죠.
6. server.open
저는 이 옵션을 정말 좋아합니다. 작지만 일단 켜두면 (대부분의 경우) 다시 끌 일이 없을 겁니다. server.open: true로 설정하면 개발 서버가 시작될 때 Vite가 자동으로 브라우저를 엽니다.
export default defineConfig({
server: {
open: true, // 개발 서버 시작 시 자동으로 브라우저 열기
},
})
특정 경로 문자열을 전달하여 해당 라우트로 바로 이동할 수도 있습니다:
server: {
open: '/dashboard', // '/dashboard' 경로로 브라우저 열기
}
조건부 설정(보너스 섹션 참조)과 함께 사용하면 vite dev를 실행할 때만 open을 설정하고, 빌드 중에는 비활성화할 수 있어 편리합니다. 사소해 보이지만, 개발 서버를 띄울 때마다 매번 브라우저를 직접 켜고 주소를 입력하는 동작이 쌓이면 은근히 귀찮습니다. server.open: true 한 줄로 이 반복 작업을 줄일 수 있어서, 저는 이 옵션을 켜면 다시 끌 일이 거의 없더라고요.
7. build.sourcemap
기본적으로 Vite는 프로덕션 빌드를 위해 소스맵을 생성하지 않으므로, 프로덕션에서 발생하는 오류는 난독화된 출력 코드를 가리키게 됩니다. 이 옵션을 켜면 스택 트레이스가 실제 소스 파일을 가리키게 됩니다.
주의: 개발 빌드에서는 소스맵이 기본으로 활성화되어 있으니, 프로덕션 빌드에서 sourcemap: true를 실수로 켜서 소스 코드가 유출되지 않도록 주의해야 합니다!
export default defineConfig({
build: {
sourcemap: true, // 프로덕션 빌드에서 소스맵 생성
},
})
npm run build를 실행한 다음 npm run preview (vite preview를 실행)를 해보세요. 개발자 도구를 열고 'Sources' 탭으로 이동하면 실제 .vue 및 .ts 파일을 볼 수 있습니다. 스택 트레이스에서 어떤 라인을 클릭하든 원본 소스로 바로 이동하므로, 디버깅하고 중단점을 추가하는 데 완벽합니다.
세 가지 모드를 사용할 수 있습니다:
build: {
sourcemap: true, // 번들과 함께 별도의 .map 파일 생성
sourcemap: 'inline', // 소스맵이 JS 파일에 직접 내장됨
sourcemap: 'hidden', // .map 파일은 생성되지만, 번들에는 참조가 없음
}
'hidden' 모드는 Sentry와 같은 오류 모니터링 서비스에 소스맵을 업로드하는 경우에 유용합니다. 브라우저가 맵 파일을 로드하지 않더라도 서버 측에서 스택 트레이스를 디코딩할 수 있습니다. 한 가지 알아둘 점은, 'hidden'은 번들에서 //# sourceMappingURL= 주석만 제거할 뿐입니다. .map 파일은 여전히 생성되며, 명시적으로 제외하지 않으면 JS 파일과 함께 배포됩니다. 소스맵을 완전히 비공개로 유지하려면 업로드하기 전에 *.map 파일을 제거하는 단계를 추가해야 합니다. 그렇지 않으면 소스맵이 프로덕션 환경에 유출될 수 있습니다!
프로덕션 환경에서 예상치 못한 에러가 발생했을 때, 난독화된 코드만 보고 디버깅하는 건 정말이지 고통스러운 일입니다. build.sourcemap을 잘 활용하면 Sentry 같은 에러 모니터링 서비스와 연동하여 실제 소스 코드 라인에서 문제를 추적할 수 있어서, 장애 대응 시간을 획기적으로 줄일 수 있습니다.
8. envPrefix
가끔 이 옵션을 찾을 때가 있는데, 특히 마이그레이션 중이라 환경 변수 접두사가 다를 때 유용합니다. 기본적으로 Vite는 VITE_ 접두사가 붙은 환경 변수만 클라이언트 코드에 노출합니다. .env 파일의 다른 모든 변수는 서버 측에 남아있죠. envPrefix는 이 접두사를 변경할 수 있게 해줍니다.
export default defineConfig({
envPrefix: 'PUBLIC_', // 환경 변수 접두사를 'PUBLIC_'으로 변경
})
이렇게 설정하면 .env 파일은 다음과 같을 수 있습니다:
PUBLIC_API_URL=https://api.example.com
PUBLIC_APP_NAME=My App
SECRET_DB_PASSWORD=supersecret
그리고 컴포넌트에서는:
import.meta.env.PUBLIC_API_URL // "https://api.example.com"
import.meta.env.PUBLIC_APP_NAME // "My App"
import.meta.env.SECRET_DB_PASSWORD // undefined, 브라우저로 전송되지 않음
오직 설정한 접두사와 일치하는 변수만 번들에 포함됩니다. 나머지 모든 변수는 동일한 .env 파일에 있더라도 빌드 시점에 제거됩니다.
Create React App (REACT_APP_)이나 Next.js (NEXT_PUBLIC_)에서 마이그레이션하는 경우, 모든 변수 이름을 변경할 필요 없이 기존의 명명 규칙을 그대로 유지할 수 있습니다. 또한 배열을 전달하여 여러 접두사를 노출할 수도 있습니다:
envPrefix: ['PUBLIC_', 'APP_'] // 'PUBLIC_' 또는 'APP_' 접두사 변수 노출
레거시 프로젝트를 Vite로 마이그레이션할 때, 기존에 사용하던 환경 변수(REACT_APP_, NEXT_PUBLIC_ 등) 접두사를 일일이 VITE_로 바꾸는 작업은 생각보다 공수가 많이 듭니다. envPrefix를 활용하면 이런 불필요한 리팩토링을 피하고 기존 설정을 그대로 사용할 수 있어 개발 시간을 크게 단축할 수 있습니다.
보너스: 조건부 설정(conditional config) 및 define
이 보너스는 좀 더 심화된 사용자분들을 위한 내용입니다! 관심 있으시면 댓글로 알려주세요! defineConfig에 객체 대신 함수를 전달할 수 있습니다. 이 함수는 command ('serve' 또는 'build')와 mode ('development' 또는 'production')를 인자로 받으므로, 컨텍스트에 따라 설정을 변경할 수 있습니다:
export default defineConfig(({ command, mode }) => ({
server: {
open: command === 'serve', // 'serve' 명령일 때만 브라우저 열기
},
build: {
sourcemap: mode !== 'production', // 'production' 모드가 아닐 때만 소스맵 생성
},
}))
define 옵션은 컴파일 시점에 전역 상수를 빌드에 삽입합니다. 값은 출력 코드에 직접 인라인되므로 런타임 비용이 전혀 없습니다:
define: {
__APP_VERSION__: JSON.stringify('1.0.0'), // 앱 버전
__BUILD_DATE__: JSON.stringify(new Date().toISOString()), // 빌드 날짜
}
TypeScript가 이 상수들을 인식하도록 vite-env.d.ts에 타입 선언을 추가해야 합니다:
declare const __APP_VERSION__: string
declare const __BUILD_DATE__: string
이 '보너스' 옵션들은 개발 환경의 유연성을 극대화하는 고급 기능이죠. 특히 define으로 버전 정보나 빌드 날짜 같은 것을 컴파일 시점에 주입해두면, 앱 내에서 이 정보를 쉽게 접근할 수 있어서 운영 및 디버깅에 매우 유용합니다.
마무리 및 정리
이 글에서 다룬 대부분의 설정은 vite.config.ts 파일 내에서만 변경되는 것들입니다. 하지만 몇몇 옵션은 다른 파일에도 영향을 미칩니다: tsconfigPaths는 tsconfig.json 파일에 paths 설정이 필요하고, envPrefix는 .env 파일과 함께 사용되며, define은 vite-env.d.ts에 타입 선언이 필요합니다. 어떤 옵션이든 되돌리려면 vite.config.ts에서 해당 설정을 제거하면 Vite가 기본값으로 폴백(fallback)됩니다.
자주 묻는 질문 (FAQ)
Q. Vite에서 TypeScript 경로 별칭이 작동하지 않는 이유는 무엇인가요?
A. tsconfig.json 파일에서 paths가 최상위 레벨이 아닌 compilerOptions 내부에 있는지 확인하세요. Vite 8의 빌트인 resolve.tsconfigPaths: true는 compilerOptions.paths에서만 별칭을 읽습니다. 최상위 레벨의 paths 키는 조용히 무시됩니다.
Q. Vite의 resolve.alias와 resolve.tsconfigPaths의 차이점은 무엇인가요?
A. resolve.alias는 vite.config.ts에 직접 정의되며 순수 JavaScript를 포함한 모든 프로젝트에서 작동합니다. resolve.tsconfigPaths는 tsconfig.json에서 별칭을 읽으며 TypeScript가 필요합니다. 단일 진실 공급원을 원한다면 tsconfigPaths를, JS 프로젝트나 모노레포에서는 alias를 사용하세요.
Q. Vite의 server.proxy가 CORS 오류를 해결하나요?
A. 네, 해결합니다. 하지만 더 중요한 목적은 개발 환경을 프로덕션 환경과 일치시키는 것입니다. 프록시는 Vite 개발 서버를 통해 요청을 라우팅하므로 브라우저는 교차 출처 요청을 하지 않습니다. 백엔드에 CORS 헤더를 추가할 필요 없이, 서버 설정에 Access-Control-Allow-Origin: localhost:5173을 추가하는 것보다 훨씬 깔끔한 방법입니다.
Q. Vite 프로덕션 소스맵은 배포해도 안전한가요?
A. sourcemap: 'hidden'은 .map 파일을 생성하지만 번들에는 참조하지 않으므로 브라우저는 이 파일을 로드하지 않습니다. Sentry와 같은 서비스에 업로드하여 비공개로 스택 트레이스를 디코딩할 수 있습니다. 주의할 점은, .map 파일은 여전히 빌드되며 업로드하기 전에 *.map 파일을 제거하는 단계를 추가하지 않으면 배포될 수 있다는 것입니다.
Q. Vite는 어떤 환경 변수를 브라우저에 노출하나요?
A. 기본적으로 VITE_ 접두사가 붙은 변수(또는 사용자 지정 envPrefix로 설정한 접두사)만 노출합니다. .env 파일의 다른 모든 변수는 빌드 시점에 제거되어 브라우저로 전송되지 않습니다. 여기에는 데이터베이스 비밀번호나 API 키 등 접두사가 없는 비밀 정보도 포함됩니다.
Q. server.forwardConsole은 모든 프레임워크에서 작동하나요?
A. 네, Vite 개발 서버 기능이므로 프레임워크에 구애받지 않습니다. Vue, React, Svelte 및 다른 모든 Vite 기반 설정에서 작동합니다. Vite는 @vercel/detect-agent를 통해 AI 코딩 에이전트를 감지하면 자동으로 활성화하지만, 그렇지 않은 경우 기본값은 false입니다.
오늘 살펴본 forwardConsole, tsconfigPaths는 Vite 8에서 새롭게 추가된 강력한 옵션이며, proxy, hmr.overlay, resolve.alias, server.open, build.sourcemap, envPrefix는 이미 존재했지만 많은 개발자들이 놓치기 쉬운 유용한 설정들입니다. 이 옵션들을 잘 활용하면 개발 경험을 한층 더 끌어올릴 수 있을 겁니다.
이 모든 데모 프로젝트는 https://github.com/ErikCH/vite-config-tips에서 확인할 수 있습니다.
올해 VueConf에서 강연하는 제 모습입니다!

이 글은 AWS 개발자 옹호자(Developer Advocate)인 Erik Hanchett가 작성했습니다. 그는 programwitherik.com에서 프론트엔드 개발, AWS, 그리고 AI/에이전트에 대한 내용을 다룹니다.
원문: https://dev.to/erikch/8-vite-config-options-every-developer-should-know-vite-8-22im 수집일: 2026-05-26 01:55:38