이미지 로딩 중...
AI Generated
2025. 11. 24. · 5 Views
Vite TypeScript 설정 완벽 가이드
Vite 프로젝트에서 TypeScript를 제대로 활용하는 방법을 배워봅니다. tsconfig 설정부터 타입 체크, path alias까지 실무에 바로 적용할 수 있는 모든 것을 다룹니다.
목차
- Vite에서_TypeScript_설정
- tsconfig.json_최적_구성
- 타입_체크_vs_빌드_분리
- vite-plugin-checker_활용
- path_alias_설정
- d.ts_파일_자동_생성
1. Vite에서_TypeScript_설정
시작하며
여러분이 새로운 Vite 프로젝트를 만들었는데, TypeScript 파일에서 자꾸 빨간 줄이 나타나거나, 빌드는 성공하는데 타입 에러가 발견되지 않는 경험을 해보셨나요? 이런 문제는 Vite의 독특한 TypeScript 처리 방식 때문에 발생합니다.
Vite는 빠른 개발 경험을 위해 TypeScript를 단순히 JavaScript로 변환만 하고, 타입 검사는 별도로 진행하지 않습니다. 바로 이럴 때 필요한 것이 올바른 Vite TypeScript 설정입니다.
이 설정을 통해 개발 속도는 유지하면서도 타입 안전성을 확보할 수 있습니다.
개요
간단히 말해서, Vite에서 TypeScript를 사용한다는 것은 개발 환경과 빌드 환경 모두에서 타입 안전성을 보장하도록 설정하는 것입니다. Vite는 esbuild를 사용해서 TypeScript를 매우 빠르게 변환하지만, 타입 검사는 하지 않습니다.
실제 프로젝트에서 개발 중에는 에러가 없는 것처럼 보이다가, CI/CD 파이프라인에서 갑자기 타입 에러가 발생하는 경우를 방지하려면 제대로 된 설정이 필요합니다. 기존 Create React App이나 다른 도구들은 개발 서버에서 타입 체크까지 자동으로 해주었다면, Vite는 속도를 위해 이를 분리했습니다.
그래서 우리가 직접 설정해야 합니다. 핵심은 vite.config.ts 설정, TypeScript 컴파일러 옵션, 그리고 개발 중 실시간 타입 체크를 위한 플러그인 설정입니다.
이 세 가지를 제대로 구성하면 빠른 개발 경험과 타입 안전성을 동시에 얻을 수 있습니다.
코드 예제
// vite.config.ts - 기본 TypeScript 설정
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
// esbuild가 TypeScript를 JavaScript로 변환
esbuild: {
// JSX 자동 변환 설정
jsx: 'automatic',
// 프로덕션 빌드에서 console 제거 (선택사항)
drop: ['console', 'debugger'],
},
// 빌드 설정
build: {
// 타입 체크는 별도로 수행
// tsc --noEmit을 package.json script에 추가
sourcemap: true,
}
})
설명
이것이 하는 일: Vite가 TypeScript 파일을 어떻게 처리할지 기본 설정을 정의합니다. 첫 번째로, plugins 배열에 react() 플러그인을 추가합니다.
이 플러그인이 JSX를 처리하고, Fast Refresh(코드 변경 시 즉시 반영)를 가능하게 합니다. React를 사용하지 않는다면 vue()나 다른 프레임워크 플러그인을 사용하면 됩니다.
그 다음으로, esbuild 설정이 실제 TypeScript 변환을 담당합니다. esbuild는 Go 언어로 작성되어 매우 빠르지만, 타입 체크는 하지 않습니다.
단순히 타입 정보를 제거하고 JavaScript로 변환만 합니다. jsx: 'automatic' 옵션은 React 17 이상에서 import React를 생략할 수 있게 해줍니다.
마지막으로, build 설정에서 sourcemap을 활성화하면 프로덕션에서도 디버깅이 쉬워집니다. 중요한 점은 Vite 빌드 자체는 타입 에러가 있어도 성공한다는 것입니다.
그래서 package.json에 "type-check": "tsc --noEmit" 스크립트를 추가하고, 빌드 전에 실행하도록 설정해야 합니다. 여러분이 이 설정을 사용하면 초고속 개발 서버와 빌드 시간을 경험하면서도, 별도의 타입 체크 과정을 통해 타입 안전성을 확보할 수 있습니다.
CI/CD에서 type-check를 먼저 실행하도록 설정하면, 타입 에러가 있는 코드가 배포되는 것을 방지할 수 있습니다.
실전 팁
💡 package.json에 "type-check": "tsc --noEmit"를 추가하고, "build": "tsc --noEmit && vite build"로 설정하면 빌드 전 자동으로 타입 체크가 실행됩니다.
💡 vite.config.ts 파일 자체도 TypeScript로 작성하면 설정 옵션에 자동완성과 타입 체크가 적용되어 실수를 줄일 수 있습니다.
💡 esbuild의 drop 옵션으로 프로덕션 빌드에서 console.log를 자동으로 제거할 수 있어, 민감한 정보 노출을 방지하고 번들 크기를 줄일 수 있습니다.
💡 Vite 개발 서버는 타입 에러를 무시하므로, IDE(VS Code)의 TypeScript 서버를 활용해 실시간으로 에러를 확인하는 습관을 들이세요.
2. tsconfig.json_최적_구성
시작하며
여러분의 프로젝트에서 import 경로가 엉망이거나, 최신 JavaScript 기능을 사용했는데 빌드에서 에러가 나거나, 라이브러리 타입이 제대로 인식되지 않는 문제를 겪어본 적 있나요? 이런 모든 문제는 tsconfig.json 설정이 프로젝트에 맞지 않기 때문에 발생합니다.
TypeScript 컴파일러는 이 파일의 설정에 따라 타입 체크 엄격성, 모듈 해석 방식, 출력 형식 등 모든 것을 결정합니다. 바로 이럴 때 필요한 것이 Vite 프로젝트에 최적화된 tsconfig.json 구성입니다.
올바른 설정으로 타입 안전성을 극대화하고 개발 경험을 향상시킬 수 있습니다.
개요
간단히 말해서, tsconfig.json은 TypeScript 컴파일러에게 "어떻게 타입을 검사하고, 어떤 파일을 포함하며, 어떤 형식으로 출력할지"를 알려주는 설정 파일입니다. Vite 프로젝트에서는 특히 몇 가지 중요한 옵션이 있습니다.
module: "ESNext"는 최신 ES 모듈을 사용하도록 하고, moduleResolution: "bundler"는 Vite 같은 번들러 환경에 최적화된 모듈 해석을 사용합니다. 예를 들어, 파일 확장자 없이 import할 때 자동으로 .ts, .tsx 파일을 찾아주는 기능입니다.
기존에는 target을 낮은 버전(ES5)으로 설정했다면, Vite에서는 ESNext로 설정하고 빌드 도구에게 변환을 맡깁니다. 이렇게 하면 개발 중에는 최신 문법을 그대로 사용하고, 프로덕션 빌드 시에만 브라우저 호환성에 맞게 변환됩니다.
핵심 옵션은 strict: true(엄격한 타입 체크), skipLibCheck: true(외부 라이브러리 타입 체크 생략으로 빌드 속도 향상), resolveJsonModule: true(JSON 파일 import 허용), 그리고 types 배열(전역 타입 정의 지정)입니다. 이들을 제대로 설정하면 타입 안전성과 개발 생산성이 크게 향상됩니다.
코드 예제
// tsconfig.json - Vite 프로젝트 최적 설정
{
"compilerOptions": {
// 변환 대상: 최신 문법 사용 (Vite가 변환 담당)
"target": "ESNext",
// 모듈 시스템: ES 모듈 사용
"module": "ESNext",
// 모듈 해석: 번들러 환경 최적화
"moduleResolution": "bundler",
// JSX 처리: React 자동 import
"jsx": "react-jsx",
// 엄격한 타입 체크 활성화
"strict": true,
// 외부 라이브러리 d.ts 체크 건너뛰기 (속도 향상)
"skipLibCheck": true,
// JSON 파일 import 허용
"resolveJsonModule": true,
// CommonJS/ES6 모듈 상호 운용
"esModuleInterop": true,
// import 시 대소문자 엄격 체크
"forceConsistentCasingInFileNames": true,
// 사용하지 않는 로컬 변수 에러
"noUnusedLocals": true,
// 사용하지 않는 파라미터 에러
"noUnusedParameters": true,
// 전역 타입 정의 (Vite 환경변수 등)
"types": ["vite/client"]
},
// 타입 체크 대상 파일
"include": ["src/**/*"],
// 타입 체크 제외 파일
"exclude": ["node_modules", "dist"]
}
설명
이것이 하는 일: TypeScript 컴파일러가 여러분의 코드를 어떻게 검사하고 처리할지 모든 규칙을 정의합니다. 첫 번째로, target과 module 설정은 출력 형식을 결정합니다.
ESNext로 설정하면 TypeScript는 최신 JavaScript 문법을 그대로 유지하고, Vite/esbuild가 나중에 브라우저 호환 코드로 변환합니다. 이렇게 하면 개발 중에는 빠르게 동작하고, 프로덕션에서는 필요한 만큼만 폴리필이 추가됩니다.
그 다음으로, moduleResolution: "bundler"는 Vite 같은 모던 번들러를 위한 설정입니다. 이 옵션은 import 시 파일 확장자를 생략할 수 있게 하고, package.json의 exports 필드를 올바르게 해석하며, 조건부 export도 지원합니다.
예를 들어, import Button from './Button'이라고 쓰면 Button.tsx를 자동으로 찾아줍니다. 세 번째로, strict: true는 매우 중요합니다.
이 옵션 하나가 strictNullChecks, noImplicitAny 등 10가지 이상의 엄격한 타입 체크를 활성화합니다. 처음에는 에러가 많이 나서 불편할 수 있지만, 런타임 에러를 사전에 방지해주는 강력한 안전장치입니다.
네 번째로, skipLibCheck: true는 node_modules 안의 .d.ts 파일 타입 체크를 건너뜁니다. 외부 라이브러리의 타입 에러 때문에 빌드가 실패하는 것을 방지하고, 타입 체크 속도를 크게 향상시킵니다.
마지막으로, types: ["vite/client"]는 Vite의 환경변수(import.meta.env) 같은 전역 타입을 인식하게 합니다. 이 설정이 없으면 import.meta.env.VITE_API_URL 같은 코드에서 타입 에러가 발생합니다.
여러분이 이 설정을 사용하면 코드 작성 중 실시간으로 타입 에러를 잡아내고, null/undefined 관련 버그를 사전에 방지하며, IDE의 자동완성 기능을 최대한 활용할 수 있습니다. 특히 strict 모드는 코드 품질을 크게 향상시킵니다.
실전 팁
💡 strict: true가 너무 엄격하다면, 개별 옵션(strictNullChecks, noImplicitAny 등)을 하나씩 활성화하면서 점진적으로 적용할 수 있습니다.
💡 noUnusedLocals와 noUnusedParameters를 켜면 사용하지 않는 변수를 자동으로 찾아주어 코드를 깔끔하게 유지할 수 있습니다.
💡 paths 옵션(나중에 설명)을 추가하기 전에 먼저 이 기본 설정이 제대로 작동하는지 확인하세요. 기본이 탄탄해야 path alias도 문제없이 작동합니다.
💡 tsconfig.json을 수정한 후에는 IDE(VS Code)를 재시작하거나 TypeScript 서버를 재시작해야 변경사항이 적용됩니다(Cmd/Ctrl + Shift + P > TypeScript: Restart TS Server).
💡 여러 환경(app, 테스트 등)을 위해 tsconfig.app.json, tsconfig.node.json 등으로 분리하고 extends로 상속받으면 설정을 깔끔하게 관리할 수 있습니다.
3. 타입_체크_vs_빌드_분리
시작하며
여러분이 Vite로 빌드를 실행했는데 몇 초 만에 성공했지만, 나중에 프로덕션에서 타입 에러로 인한 버그가 발생한 경험이 있나요? 또는 CI/CD에서 갑자기 타입 에러가 발견되어 배포가 실패한 적이 있나요?
이런 문제는 Vite가 빌드 속도를 위해 타입 체크를 생략하기 때문에 발생합니다. 빌드가 빠른 건 좋지만, 타입 안전성이 보장되지 않으면 런타임 에러로 이어질 수 있습니다.
바로 이럴 때 필요한 것이 타입 체크와 빌드를 분리하는 전략입니다. 개발 중에는 빠른 피드백을, 배포 전에는 완벽한 타입 안전성을 확보할 수 있습니다.
개요
간단히 말해서, 타입 체크와 빌드 분리는 TypeScript 컴파일러(tsc)로 타입만 검사하고, Vite로 실제 빌드를 수행하는 방식입니다. Vite는 esbuild로 TypeScript를 JavaScript로 변환하기만 하고 타입은 검사하지 않습니다.
이 방식은 엄청나게 빠르지만(기존 대비 10-100배), 타입 에러가 있어도 빌드가 성공합니다. 실제 프로젝트에서는 "빌드 전에 타입 체크를 먼저 실행하고, 통과하면 빌드"하는 두 단계 프로세스가 필요합니다.
기존 Create React App이나 webpack은 빌드 중에 타입 체크도 함께 했다면, Vite는 이 둘을 완전히 분리했습니다. 이는 개발 서버 시작이 느려지는 것을 방지하고, 개발자가 타입 체크 타이밍을 직접 제어할 수 있게 합니다.
핵심은 tsc --noEmit 명령어입니다. --noEmit 플래그는 "JavaScript 파일을 생성하지 말고, 타입 체크만 해라"는 의미입니다.
이렇게 하면 타입 에러만 찾아내고, 실제 코드 변환은 Vite에게 맡깁니다. package.json 스크립트를 적절히 구성하면 이 과정을 자동화할 수 있습니다.
코드 예제
// package.json - 타입 체크와 빌드 분리 스크립트
{
"scripts": {
// 개발 서버: 타입 체크 없이 빠르게 시작
"dev": "vite",
// 타입 체크만 수행 (JavaScript 생성 안 함)
"type-check": "tsc --noEmit",
// 타입 체크 후 빌드 (순차 실행)
"build": "tsc --noEmit && vite build",
// 타입 체크를 watch 모드로 (개발 중 백그라운드 실행)
"type-check:watch": "tsc --noEmit --watch",
// 타입 체크와 개발 서버를 동시에 실행
"dev:full": "npm-run-all --parallel dev type-check:watch"
},
"devDependencies": {
"npm-run-all": "^4.1.5"
}
}
설명
이것이 하는 일: 타입 안전성과 빌드 속도를 모두 확보하기 위한 워크플로우를 구성합니다. 첫 번째로, dev 스크립트는 순수하게 Vite 개발 서버만 실행합니다.
타입 체크 없이 즉시 시작되어 1-2초 안에 개발을 시작할 수 있습니다. 타입 에러가 있어도 서버가 실행되므로, IDE에서 타입 에러를 확인하면서 개발을 진행합니다.
그 다음으로, type-check 스크립트는 TypeScript 컴파일러를 실행하되 --noEmit 플래그로 JavaScript 파일을 생성하지 않습니다. 오직 타입 검사만 수행하고 에러를 출력합니다.
이 명령은 프로젝트 전체를 스캔하므로 파일이 많으면 10-30초 정도 걸릴 수 있습니다. 세 번째로, build 스크립트에서 &&(AND) 연산자를 사용합니다.
이는 "왼쪽 명령이 성공하면 오른쪽 명령 실행"을 의미합니다. tsc --noEmit이 타입 에러를 발견하면 exit code 1로 실패하고, vite build는 실행되지 않습니다.
이렇게 하면 타입 에러가 있는 코드가 절대 프로덕션에 배포되지 않습니다. 네 번째로, type-check:watch는 --watch 모드로 파일이 변경될 때마다 자동으로 타입 체크를 다시 실행합니다.
터미널을 하나 더 열어서 이 명령을 백그라운드로 실행해두면, 코드 작성과 동시에 타입 에러를 즉시 확인할 수 있습니다. 마지막으로, dev:full 스크립트는 npm-run-all 패키지를 사용해 개발 서버와 타입 체크를 동시에(parallel) 실행합니다.
한 번의 명령으로 완전한 개발 환경을 구성할 수 있습니다. 여러분이 이 워크플로우를 사용하면 개발 중에는 초고속으로 작업하고, 커밋하기 전에 type-check로 타입 에러를 확인하며, CI/CD에서는 빌드 전에 자동으로 타입 체크가 실행되어 안전한 배포를 보장할 수 있습니다.
실전 팁
💡 Git hooks(husky)를 사용해 커밋 전에 자동으로 type-check를 실행하도록 설정하면, 타입 에러가 있는 코드가 리포지토리에 푸시되는 것을 방지할 수 있습니다.
💡 CI/CD 파이프라인에서는 npm run build가 아닌 npm run type-check && npm run build를 명시적으로 실행하면, 타입 체크 실패 시 즉시 빌드를 중단하고 로그를 명확하게 볼 수 있습니다.
💡 타입 체크가 너무 느리다면 tsconfig.json의 include를 좁히거나, incremental: true 옵션으로 증분 컴파일을 활성화하면 두 번째 실행부터 훨씬 빨라집니다.
💡 개발 중에는 dev만 실행하고 IDE의 타입 체크에 의존하는 것이 가장 효율적입니다. type-check:watch는 IDE가 느리거나 여러 파일의 타입 관계를 확인할 때만 사용하세요.
💡 --pretty 플래그를 추가하면(tsc --noEmit --pretty) 타입 에러 메시지에 색상이 추가되어 읽기 쉬워집니다.
4. vite-plugin-checker_활용
시작하며
여러분이 코드를 수정하고 저장했는데, 브라우저를 새로고침해야만 타입 에러를 확인할 수 있거나, 터미널과 브라우저를 계속 왔다갔다하며 에러를 확인해야 했던 경험이 있나요? 이런 불편함은 Vite가 개발 서버에서 타입 체크를 자동으로 실행하지 않기 때문입니다.
개발 속도는 빠르지만, 타입 에러를 놓치기 쉽고, 에러를 확인하기 위해 별도 명령을 실행해야 합니다. 바로 이럴 때 필요한 것이 vite-plugin-checker입니다.
이 플러그인은 개발 서버에서 실시간으로 타입 체크를 수행하고, 에러를 브라우저 오버레이로 바로 보여줍니다.
개요
간단히 말해서, vite-plugin-checker는 Vite 개발 서버에서 TypeScript, ESLint 등의 체크를 백그라운드로 실행하고, 에러를 브라우저에 표시해주는 플러그인입니다. 이 플러그인은 별도 워커 스레드에서 타입 체크를 실행하기 때문에 개발 서버 속도에 영향을 거의 주지 않습니다.
파일을 저장하면 몇 초 후 자동으로 타입 체크가 실행되고, 에러가 있으면 브라우저에 빨간색 오버레이가 나타납니다. 실제 프로젝트에서 "저장하자마자 바로 피드백을 받고 싶지만, 개발 서버는 빠르게 유지하고 싶은" 경우에 완벽한 솔루션입니다.
기존에는 별도 터미널에서 tsc --watch를 실행하거나, IDE의 타입 에러만 의존했다면, 이제는 브라우저에서 직접 타입 에러를 확인할 수 있습니다. 특히 팀 프로젝트에서 모든 팀원이 동일한 타입 체크 경험을 하도록 강제할 수 있습니다.
핵심 기능은 typescript 체크(타입 에러), eslint 체크(코드 스타일), overlay 표시(브라우저 에러 팝업), 그리고 terminal 로그(터미널 출력)입니다. 개발 환경에서만 활성화되고 프로덕션 빌드에는 영향을 주지 않습니다.
코드 예제
// vite.config.ts - vite-plugin-checker 설정
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker'
export default defineConfig({
plugins: [
react(),
// 개발 서버에서 실시간 타입 체크
checker({
// TypeScript 타입 체크 활성화
typescript: {
// tsconfig 파일 경로 (기본값: tsconfig.json)
tsconfigPath: './tsconfig.json',
// 빌드 모드 (true: 빌드 시에도 체크)
buildMode: false,
},
// ESLint 체크도 추가 가능 (선택사항)
eslint: {
lintCommand: 'eslint "./src/**/*.{ts,tsx}"',
},
// 브라우저 오버레이 설정
overlay: {
initialIsOpen: true, // 에러 발생 시 자동으로 열기
position: 'br', // 위치: bottom-right
},
// 터미널 출력 활성화
terminal: true,
}),
],
})
설명
이것이 하는 일: 개발 중 코드를 저장할 때마다 백그라운드에서 타입 체크를 실행하고, 결과를 브라우저와 터미널에 동시에 표시합니다. 첫 번째로, checker 플러그인을 plugins 배열에 추가합니다.
이 플러그인은 Vite 개발 서버가 시작될 때 별도 워커 스레드를 생성하여 타입 체크를 준비합니다. 메인 스레드와 분리되어 있어서 개발 서버 성능에 영향을 주지 않습니다.
그 다음으로, typescript 옵션에서 타입 체크를 구성합니다. tsconfigPath로 사용할 tsconfig 파일을 지정하고, buildMode: false로 설정하면 개발 모드에서만 체크합니다.
파일을 저장하면 수정된 파일과 그 파일에 의존하는 다른 파일들을 모두 다시 체크합니다. 세 번째로, eslint 옵션을 추가하면 타입 체크와 함께 코드 스타일도 검사할 수 있습니다.
lintCommand에 ESLint 명령을 지정하면, 타입 에러뿐 아니라 사용하지 않는 import, 잘못된 코딩 패턴 등도 동시에 찾아냅니다. 네 번째로, overlay 설정이 사용자 경험의 핵심입니다.
타입 에러가 발생하면 브라우저 화면 위에 반투명한 빨간색 팝업이 나타나 에러 메시지, 파일 경로, 라인 번호를 보여줍니다. 에러를 클릭하면 에디터로 바로 이동할 수 있습니다(VS Code 설정 필요).
마지막으로, terminal: true는 브라우저뿐 아니라 터미널에도 에러를 출력합니다. 브라우저를 보지 않고 개발하는 경우에도 터미널에서 에러를 확인할 수 있습니다.
여러분이 이 플러그인을 사용하면 코드 저장 즉시 타입 에러를 시각적으로 확인하고, 별도 터미널이나 IDE 창을 확인할 필요 없이 브라우저에서 모든 것을 처리하며, 팀 전체가 동일한 타입 체크 환경을 공유할 수 있습니다.
실전 팁
💡 대규모 프로젝트에서는 타입 체크가 느릴 수 있으므로, typescript.buildMode를 false로 유지하고 CI/CD에서만 전체 체크를 수행하세요.
💡 overlay.initialIsOpen을 false로 설정하면 에러가 발생해도 오버레이가 자동으로 열리지 않고, 터미널에서만 확인할 수 있어 개발 흐름이 끊기지 않습니다.
💡 eslint 체크를 추가할 때는 .eslintignore를 제대로 설정하지 않으면 node_modules까지 체크해서 매우 느려질 수 있으니 주의하세요.
💡 타입 체크가 너무 자주 실행되어 불편하다면, 플러그인을 제거하고 pre-commit hook이나 CI/CD에서만 체크하는 것도 좋은 전략입니다.
💡 VS Code의 "Open in Editor" 기능을 활성화하려면 설정에서 "Debug: Open Link Command"를 설정해야 합니다.
5. path_alias_설정
시작하며
여러분의 프로젝트에서 import 경로가 '../../../components/Button' 같이 상대 경로가 복잡하게 꼬이거나, 파일을 이동할 때마다 모든 import를 수정해야 했던 경험이 있나요? 이런 문제는 상대 경로 기반 import의 근본적인 한계입니다.
파일 구조가 깊어질수록 경로가 복잡해지고, 리팩토링할 때마다 여러 파일을 수정해야 합니다. 바로 이럴 때 필요한 것이 path alias 설정입니다.
@/components/Button 같은 절대 경로로 간편하게 import하고, 파일 위치가 바뀌어도 import는 그대로 유지할 수 있습니다.
개요
간단히 말해서, path alias는 import 경로에 사용할 수 있는 단축 별칭으로, 프로젝트 루트나 특정 폴더를 짧은 이름으로 참조할 수 있게 해줍니다. 가장 흔한 패턴은 @를 src 폴더의 별칭으로 사용하는 것입니다.
이렇게 하면 import Button from '@/components/Button'처럼 어디서든 동일한 경로로 import할 수 있습니다. 실제 프로젝트에서 components, utils, hooks 같은 공통 폴더에 접근할 때 매번 상대 경로를 계산할 필요가 없어집니다.
기존에는 ../../utils/formatDate 같은 상대 경로를 사용했다면, 이제는 @/utils/formatDate로 통일할 수 있습니다. 파일을 다른 폴더로 이동해도 import 경로는 바뀌지 않습니다.
핵심은 두 곳에서 설정해야 한다는 것입니다: tsconfig.json(TypeScript 컴파일러용)과 vite.config.ts(Vite 번들러용). 두 설정이 일치하지 않으면 IDE에서는 정상이지만 빌드 시 에러가 발생하거나, 그 반대 상황이 생깁니다.
코드 예제
// 1. tsconfig.json - TypeScript path alias 설정
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@utils/*": ["./src/utils/*"],
"@hooks/*": ["./src/hooks/*"]
}
}
}
// 2. vite.config.ts - Vite path alias 설정
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
// @를 src 폴더로 매핑
'@': path.resolve(__dirname, './src'),
// 세부 폴더별 별칭 (선택사항)
'@components': path.resolve(__dirname, './src/components'),
'@utils': path.resolve(__dirname, './src/utils'),
'@hooks': path.resolve(__dirname, './src/hooks'),
},
},
})
// 3. 사용 예시
// 기존 상대 경로
import Button from '../../../components/Button'
// path alias 사용
import Button from '@/components/Button'
설명
이것이 하는 일: import 경로에 사용할 단축 별칭을 정의하고, TypeScript와 Vite가 이를 실제 파일 경로로 올바르게 해석하도록 설정합니다. 첫 번째로, tsconfig.json에서 baseUrl과 paths를 설정합니다.
baseUrl은 상대 경로의 기준점이고, paths는 실제 별칭 매핑입니다. "@/": ["./src/"]는 "@/로 시작하는 모든 import를 ./src/로 변환하라"는 의미입니다.
이 설정으로 IDE(VS Code)가 자동완성과 타입 체크를 올바르게 수행합니다. 그 다음으로, vite.config.ts에서 resolve.alias를 설정합니다.
path.resolve(__dirname, './src')는 Node.js의 절대 경로를 생성합니다. __dirname은 현재 vite.config.ts 파일의 위치(프로젝트 루트)이고, 여기에 ./src를 합쳐서 완전한 절대 경로를 만듭니다.
이 설정으로 Vite가 빌드 시 @/를 실제 경로로 변환합니다. 세 번째로, 세부 폴더별 별칭(@components, @utils 등)은 선택사항입니다.
@/components/Button과 @components/Button 둘 다 작동하지만, 전자가 더 유연합니다. 폴더 구조가 바뀌어도 @ 하나만 수정하면 되기 때문입니다.
네 번째로, 두 설정이 정확히 일치해야 합니다. tsconfig.json에는 있는데 vite.config.ts에 없으면 개발 서버에서 에러가 나고, 반대면 IDE에서 타입 에러가 표시됩니다.
별칭을 추가할 때는 항상 두 파일을 동시에 수정하세요. 마지막으로, 사용할 때는 import Button from '@/components/Button'처럼 작성합니다.
파일 위치와 무관하게 동일한 경로를 사용할 수 있어, 코드 리뷰 시 파일 구조를 파악하기도 쉽고, 파일을 이동해도 import를 수정할 필요가 없습니다. 여러분이 이 설정을 사용하면 import 경로가 깔끔해지고, 파일을 이동할 때 유지보수가 쉬우며, 새로운 팀원도 파일 위치를 쉽게 파악할 수 있습니다.
특히 components, utils, hooks 같은 공통 폴더에 자주 접근하는 경우 개발 생산성이 크게 향상됩니다.
실전 팁
💡 @보다 더 명시적인 별칭(~, $, #)을 사용할 수도 있지만, @가 React/Vue 생태계에서 사실상 표준이므로 @를 권장합니다.
💡 너무 많은 세부 별칭(@components, @utils 등)을 만들지 말고, @/ 하나만 사용하는 것이 설정 관리가 쉽습니다.
💡 path 모듈의 타입을 인식시키기 위해 npm install -D @types/node를 설치해야 합니다.
💡 Monorepo 환경에서는 각 패키지마다 별도 별칭(@app/, @shared/ 등)을 설정하면 패키지 간 의존성을 명확히 할 수 있습니다.
💡 Jest나 Vitest 같은 테스트 러너를 사용한다면, 해당 설정 파일에도 동일한 path alias를 추가해야 테스트가 정상 작동합니다.
6. d.ts_파일_자동_생성
시작하며
여러분이 JavaScript 라이브러리를 사용하는데 타입이 없어서 any로 사용하거나, 이미지나 CSS 모듈을 import할 때 타입 에러가 발생하거나, 환경변수를 사용할 때 자동완성이 안 되는 경험을 해보셨나요? 이런 문제는 TypeScript가 해당 파일이나 모듈의 타입 정의(.d.ts 파일)를 찾지 못하기 때문에 발생합니다.
타입 정의가 없으면 any 타입으로 처리되어 타입 안전성이 사라집니다. 바로 이럴 때 필요한 것이 d.ts 파일 자동 생성입니다.
커스텀 타입 정의를 만들어 TypeScript가 인식하게 하거나, 도구를 사용해 자동으로 타입을 생성할 수 있습니다.
개요
간단히 말해서, .d.ts 파일은 "타입 선언(Declaration) 파일"로, 실제 코드 없이 타입 정보만 담고 있는 TypeScript 파일입니다. Vite 프로젝트에서는 세 가지 상황에서 d.ts 파일이 필요합니다.
첫째, 이미지나 CSS 모듈 같은 비 TypeScript 파일을 import할 때. 둘째, 타입이 없는 JavaScript 라이브러리를 사용할 때.
셋째, 환경변수 같은 전역 변수에 타입을 추가할 때입니다. 실제 프로젝트에서 import logo from './logo.png' 같은 코드에서 타입 에러가 나는 것을 방지하려면 PNG 파일에 대한 타입 정의가 필요합니다.
기존에는 .d.ts 파일을 수동으로 작성했다면, 이제는 vite-plugin-dts 같은 플러그인으로 자동 생성할 수 있습니다. 특히 라이브러리를 개발할 때 소스 코드에서 타입 정의를 자동으로 추출하여 배포할 수 있습니다.
핵심은 세 가지입니다: src/vite-env.d.ts(Vite 기본 타입), src/custom.d.ts(커스텀 모듈 타입), 그리고 vite-plugin-dts(자동 생성 플러그인)입니다. 이들을 조합하면 모든 타입 문제를 해결할 수 있습니다.
코드 예제
// 1. src/vite-env.d.ts - Vite 기본 환경 타입
/// <reference types="vite/client" />
// 환경변수 타입 정의
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
// 다른 환경변수 추가...
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
// 2. src/custom.d.ts - 커스텀 모듈 타입
// 이미지 파일 타입
declare module '*.png' {
const src: string
export default src
}
declare module '*.jpg' {
const src: string
export default src
}
// CSS 모듈 타입
declare module '*.module.css' {
const classes: { [key: string]: string }
export default classes
}
// SVG를 React 컴포넌트로 import
declare module '*.svg' {
import React from 'react'
const SVG: React.FC<React.SVGProps<SVGSVGElement>>
export default SVG
}
// 3. vite.config.ts - 자동 타입 생성 (라이브러리용)
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [
dts({
// d.ts 파일 생성 위치
outDir: 'dist/types',
// src 폴더의 모든 TS 파일에서 타입 추출
include: ['src/**/*'],
// node_modules 제외
exclude: ['node_modules'],
}),
],
})
설명
이것이 하는 일: TypeScript가 인식하지 못하는 파일이나 모듈에 대한 타입 정보를 제공하여, 모든 import와 전역 변수에 타입 안전성을 부여합니다. 첫 번째로, vite-env.d.ts는 Vite의 기본 타입과 환경변수 타입을 정의합니다.
/// <reference types="vite/client" />는 Vite가 제공하는 전역 타입(import.meta.env, import.meta.hot 등)을 가져옵니다. ImportMetaEnv 인터페이스를 확장하면 환경변수마다 구체적인 타입을 지정할 수 있어, import.meta.env.VITE_API_URL을 사용할 때 자동완성과 타입 체크가 작동합니다.
그 다음으로, custom.d.ts에서 비 TypeScript 파일의 타입을 정의합니다. declare module '*.png'는 "모든 .png 파일은 string 타입의 default export를 가진다"고 선언합니다.
이렇게 하면 import logo from './logo.png'에서 logo가 string(이미지 URL) 타입으로 인식됩니다. CSS 모듈의 경우 { [key: string]: string } 타입으로 정의하면 classes.button처럼 접근할 때 자동완성이 작동합니다.
세 번째로, SVG 모듈 선언은 SVGR 같은 도구를 사용할 때 필요합니다. SVG를 React 컴포넌트로 import하는 경우, React.FC<React.SVGProps<SVGSVGElement>> 타입으로 정의하면 <Logo width={100} />처럼 props를 전달할 때 타입 체크가 됩니다.
네 번째로, vite-plugin-dts는 라이브러리를 개발할 때 사용합니다. 이 플러그인은 src 폴더의 모든 TypeScript 파일을 분석하여 대응하는 .d.ts 파일을 자동으로 생성합니다.
예를 들어, src/Button.tsx에서 export interface ButtonProps를 정의하면, dist/types/Button.d.ts가 자동으로 생성되어 라이브러리 사용자가 타입 정보를 얻을 수 있습니다. 마지막으로, 생성된 d.ts 파일은 package.json의 types 필드에 지정해야 합니다: "types": "dist/types/index.d.ts".
이렇게 하면 npm에 배포했을 때 다른 사용자가 여러분의 라이브러리를 import하면 자동으로 타입이 인식됩니다. 여러분이 이 설정을 사용하면 이미지나 CSS 파일을 import할 때 타입 에러가 사라지고, 환경변수 사용 시 자동완성과 타입 체크가 작동하며, 라이브러리 개발 시 타입 파일을 자동으로 생성하여 배포할 수 있습니다.
실전 팁
💡 vite-env.d.ts는 Vite 프로젝트 생성 시 자동으로 만들어지므로, 환경변수 타입만 추가하면 됩니다.
💡 TypeScript 4.7 이상에서는 moduleResolution: "bundler"를 사용하면 .d.ts 파일 없이도 일부 모듈을 인식하지만, 명시적으로 선언하는 것이 더 안전합니다.
💡 @types/ 패키지를 먼저 찾아보세요. 예를 들어 @types/node를 설치하면 Node.js 모듈(path, fs 등)의 타입을 얻을 수 있습니다.
💡 vite-plugin-dts는 빌드 시간을 늘릴 수 있으므로, 라이브러리 프로젝트에만 사용하고 일반 애플리케이션에는 사용하지 마세요.
💡 d.ts 파일을 수정한 후에는 IDE의 TypeScript 서버를 재시작해야 변경사항이 반영됩니다(Cmd/Ctrl + Shift + P > TypeScript: Restart TS Server).
댓글 (0)
함께 보면 좋은 카드 뉴스
OpenAPI/Swagger로 API 문서화 완벽 가이드
API 문서화의 표준인 OpenAPI와 Swagger를 활용하여 프론트엔드 개발자와 원활하게 협업하는 방법을 배웁니다. 스펙 작성부터 자동 문서 생성, 버전 관리까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.
예외 처리와 로깅 전략 완벽 가이드
초급 개발자를 위한 예외 처리와 로깅 전략 가이드입니다. Try-Catch부터 Sentry까지, 실무에서 바로 적용할 수 있는 에러 관리 기법을 단계별로 설명합니다.
일관된 에러 응답 설계 완벽 가이드
API 개발에서 가장 중요하면서도 간과하기 쉬운 에러 응답 설계를 다룹니다. 클라이언트와 서버가 명확하게 소통할 수 있는 표준화된 에러 응답 체계를 구축하는 방법을 배웁니다.
Vite 라이브러리 모드로 패키지 빌드하기 완벽 가이드
Vite의 라이브러리 모드를 활용하여 재사용 가능한 패키지를 빌드하는 방법을 배웁니다. lib 모드 설정부터 다양한 모듈 포맷 생성, TypeScript 선언 파일까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.
Webpack에서 Vite로 마이그레이션 완벽 가이드
레거시 Webpack 프로젝트를 최신 Vite로 안전하게 전환하는 방법을 단계별로 소개합니다. 마이그레이션 체크리스트부터 성능 비교까지, 실무에서 바로 적용할 수 있는 완벽한 가이드입니다.