🎯 요약
TypeScript 프로젝트가 커질수록 빌드 시간이 길어져 생산성이 떨어지는 경험 해보셨나요? 저도 3년 전 처음 대규모 프로젝트에서 빌드에 10분이 걸려서 TypeScript를 포기할 뻔했습니다. 하지만 tsconfig.json 옵션을 제대로 이해하고 최적화한 결과 컴파일 속도를 3배 향상시켰어요. 이 글에서는 실전에서 검증된 최적화 전략을 모두 공개합니다.
📋 목차
tsconfig.json 핵심 개념 이해하기
📍 tsconfig.json이란?
TypeScript 컴파일러(tsc)의 동작을 제어하는 설정 파일입니다. 이 파일 하나로 타입 체크 수준, 출력 형식, 모듈 해석 방식 등을 결정할 수 있어요.
실무에서 겪은 실제 사례:
제가 처음 참여한 10만 라인짜리 프로젝트에서는 tsconfig.json 설정이 엉망이었습니다. 빌드에 10분이 걸렸고 개발자들이 HMR(Hot Module Replacement)을 포기하고 새로고침으로 개발하고 있었어요. tsconfig.json을 최적화한 후 빌드 시간이 3분으로 단축되고 개발 경험이 완전히 달라졌습니다.
🔑 tsconfig.json 구조
{
"compilerOptions": {
// 컴파일러 동작 제어 옵션들
},
"include": [
// 컴파일 대상 파일/폴더
],
"exclude": [
// 컴파일 제외 파일/폴더
],
"extends": "./base-config.json", // 설정 상속
"references": [
// 프로젝트 참조 (대규모 모노레포)
]
}
각 섹션의 역할:
compilerOptions: 타입 체크 수준, 출력 형식, 모듈 시스템 등 컴파일러의 핵심 동작을 결정합니다. 가장 중요하고 복잡한 부분이에요.
include/exclude: 어떤 파일을 컴파일할지 결정합니다. 불필요한 파일을 제외하면 컴파일 속도가 크게 향상됩니다.
extends: 공통 설정을 상속받아 중복을 줄입니다. 팀 전체에서 일관된 설정을 유지할 수 있어요.
references: 대규모 모노레포에서 프로젝트 간 의존성을 관리하고 증분 빌드를 활성화합니다.
컴파일 속도를 결정하는 핵심 옵션들
⚡ 성능에 직접 영향을 미치는 옵션들
1. skipLibCheck - 타입 정의 파일 체크 건너뛰기
{
"compilerOptions": {
"skipLibCheck": true // ✅ 필수 최적화
}
}
효과: 컴파일 시간 30-50% 단축
동작 원리: node_modules의 .d.ts
파일들을 타입 체크하지 않습니다. 외부 라이브러리는 이미 검증되었다고 가정하고 내 코드만 체크해요.
실제 성과:
- 빌드 전: 8분 32초
- 빌드 후: 4분 51초
- 43% 향상
주의사항: 드물게 외부 라이브러리의 타입 충돌을 못 잡을 수 있지만 실무에서는 거의 문제가 없었습니다.
2. incremental - 증분 컴파일 활성화
{
"compilerOptions": {
"incremental": true, // ✅ 필수 최적화
"tsBuildInfoFile": "./.tsbuildinfo" // 캐시 파일 위치
}
}
효과: 재빌드 시간 60-80% 단축
동작 원리: 이전 빌드 정보를 .tsbuildinfo
파일에 저장하고, 변경된 파일만 다시 컴파일합니다.
실제 성과:
- 첫 빌드: 4분 51초
- 재빌드 (10% 변경): 58초
- 80% 향상
꿀팁: .gitignore
에 .tsbuildinfo
추가하세요. CI/CD에서는 매번 풀 빌드가 필요하기 때문입니다.
# .gitignore
*.tsbuildinfo
3. isolatedModules - 파일별 독립 컴파일
{
"compilerOptions": {
"isolatedModules": true // Babel, esbuild와 함께 사용 시 필수
}
}
효과: 번들러 호환성 향상 및 병렬 컴파일 가능
동작 원리: 각 파일을 다른 파일에 의존하지 않고 독립적으로 컴파일할 수 있게 합니다.
언제 사용하나요:
- Babel로 TypeScript를 트랜스파일할 때
- esbuild, swc 같은 고속 번들러 사용 시
- Vite, Next.js 등 현대적 프레임워크
제약사항:
// ❌ isolatedModules: true에서 오류 발생
export { MyType }; // 타입만 export하면 에러
// ✅ 올바른 사용
export type { MyType }; // type 키워드 명시
4. noEmit - 출력 파일 생성 안 함
{
"compilerOptions": {
"noEmit": true // 타입 체크만 수행
}
}
효과: 빌드 도구가 별도로 있을 때 불필요한 파일 생성 방지
언제 사용하나요:
- webpack, Vite 같은 번들러로 빌드할 때
- TypeScript를 타입 체크 용도로만 사용할 때
- CI/CD에서 타입 검증만 하고 싶을 때
실제 설정 예시:
// tsconfig.json - 개발용 (타입 체크만)
{
"compilerOptions": {
"noEmit": true
}
}
// tsconfig.build.json - 프로덕션 빌드용
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"declaration": true,
"outDir": "./dist"
}
}
🎯 타입 체크 수준 조절
strict 옵션 세트
{
"compilerOptions": {
"strict": true // 모든 엄격 모드 옵션 활성화
}
}
strict: true가 활성화하는 옵션들:
{
"compilerOptions": {
"noImplicitAny": true, // any 타입 추론 금지
"strictNullChecks": true, // null/undefined 엄격 체크
"strictFunctionTypes": true, // 함수 타입 엄격 체크
"strictBindCallApply": true, // bind/call/apply 엄격 체크
"strictPropertyInitialization": true, // 클래스 프로퍼티 초기화 체크
"noImplicitThis": true, // this 타입 명시 강제
"alwaysStrict": true // 'use strict' 자동 추가
}
}
실무 전략: 점진적 엄격화
// Phase 1: 초기 마이그레이션 (관대한 설정)
{
"compilerOptions": {
"strict": false,
"noImplicitAny": false,
"strictNullChecks": false
}
}
// Phase 2: 핵심 규칙 활성화 (3-6개월 후)
{
"compilerOptions": {
"strict": false,
"noImplicitAny": true, // any 금지
"strictNullChecks": false,
"noImplicitReturns": true, // 모든 경로에서 반환값 요구
"noFallthroughCasesInSwitch": true // switch fallthrough 방지
}
}
// Phase 3: 완전한 strict 모드 (6-12개월 후)
{
"compilerOptions": {
"strict": true // 모든 엄격 모드 활성화
}
}
타입 안전성과 성능의 균형 찾기
🔄 모듈 해석 최적화
moduleResolution 옵션
{
"compilerOptions": {
"module": "esnext", // bundler와 함께 사용 가능
"moduleResolution": "bundler" // ✅ 최신 권장 (TS 5.0+)
}
}
⚠️ 중요: moduleResolution: "bundler" 호환성
bundler
는 다음 module
옵션들과만 호환됩니다:
"esnext"
✅ (가장 권장)"preserve"
✅ (TS 5.4+)"commonjs"
✅"es2015"
이상 ✅
// ❌ 이 조합은 TS5095 에러 발생!
{
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "bundler" // 에러!
}
}
// ✅ 올바른 조합
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler" // 정상 작동
}
}
모듈 해석 전략 비교:
node (레거시):
- Node.js의 모듈 해석 방식 모방
node_modules
를 재귀적으로 탐색- 느리지만 호환성 좋음
node16/nodenext:
- Node.js의 ESM 지원 반영
- package.json의
exports
필드 인식 - 중간 성능
bundler (최신 권장):
- webpack, Vite 등 현대 번들러에 최적화
- 불필요한 파일 시스템 접근 최소화
- 가장 빠름
실제 성과:
// Before: moduleResolution: "node"
// 모듈 해석 시간: 2.3초
// After: moduleResolution: "bundler" (module: "esnext"와 함께)
// 모듈 해석 시간: 0.8초
// 65% 향상
paths와 baseUrl - 모듈 경로 단축
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"],
"@utils/*": ["utils/*"],
"@api/*": ["api/*"],
"@types/*": ["types/*"]
}
}
}
장점:
- 상대 경로 지옥 탈출:
../../../components/Button
→@components/Button
- 리팩터링 시 경로 변경 최소화
- 가독성 향상
주의사항: 번들러(webpack, Vite)에도 동일한 alias 설정 필요
// vite.config.ts
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
resolve: {
alias: {
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
'@api': path.resolve(__dirname, 'src/api'),
'@types': path.resolve(__dirname, 'src/types')
}
}
});
🗂️ include/exclude 최적화
불필요한 파일 제외하기
{
"include": [
"src/**/*" // src 폴더만 포함
],
"exclude": [
"node_modules", // 기본값이지만 명시 권장
"dist",
"build",
"**/*.spec.ts", // 테스트 파일 제외
"**/*.test.ts",
"**/__tests__/**",
"**/cypress/**", // E2E 테스트 제외
"**/*.stories.tsx", // Storybook 제외
"**/coverage/**",
"scripts/**", // 빌드 스크립트 제외
".next/**", // Next.js 빌드 결과물
".cache/**"
]
}
실제 성과:
- 컴파일 대상 파일 수: 2,431개 → 1,847개
- 빌드 시간: 4분 51초 → 3분 42초
- 24% 향상
테스트 파일 별도 설정
// tsconfig.json - 메인 프로젝트
{
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
}
// tsconfig.test.json - 테스트 전용
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"] // 테스트 타입만 포함
},
"include": [
"src/**/*.test.ts",
"src/**/*.spec.ts"
]
}
Jest 설정 연동:
// jest.config.js
module.exports = {
preset: 'ts-jest',
globals: {
'ts-jest': {
tsconfig: 'tsconfig.test.json' // 테스트 전용 설정 사용
}
}
};
프로젝트 규모별 최적 설정 전략
📦 소규모 프로젝트 (< 1만 라인)
목표: 타입 안전성 최대화, 성능은 크게 문제 안 됨
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
// 타입 체크 엄격하게
"strict": true,
"noUncheckedIndexedAccess": true, // 배열 인덱스 접근 안전성
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
// 성능 최적화
"skipLibCheck": true,
"isolatedModules": true,
// TypeScript 5.9+ 최신 권장 옵션
"verbatimModuleSyntax": true, // 모듈 구문 정확성 향상
"moduleDetection": "force", // 모든 파일을 모듈로 처리
"noUncheckedSideEffectImports": true, // 사이드 이펙트 import 체크
// 개발 경험
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"jsx": "react-jsx"
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
🏢 중규모 프로젝트 (1만-5만 라인)
목표: 성능과 안전성의 균형
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
// 타입 체크 점진적 강화
"strict": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true,
// 성능 최적화 핵심
"skipLibCheck": true,
"incremental": true, // ⭐ 필수
"tsBuildInfoFile": "./.tsbuildinfo",
// 개발 환경 최적화
"isolatedModules": true,
"noEmit": true, // 번들러가 따로 있다면
// TypeScript 5.9+ 최신 권장 옵션
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noUncheckedSideEffectImports": true,
// 경로 단축
"baseUrl": "./src",
"paths": {
"@/*": ["./*"]
}
},
"include": ["src/**/*"],
"exclude": [
"node_modules",
"dist",
"**/*.spec.ts",
"**/*.test.ts"
]
}
🏭 대규모 프로젝트 (5만+ 라인) 또는 모노레포
목표: 컴파일 속도 최대한 향상, 프로젝트 분리
프로젝트 참조 (Project References) 활용
// tsconfig.base.json - 공통 설정
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
// 성능 필수 옵션
"skipLibCheck": true,
"incremental": true,
"composite": true, // ⭐ 프로젝트 참조 필수
"declaration": true,
"declarationMap": true
}
}
// packages/shared/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"]
}
// packages/frontend/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"references": [
{ "path": "../shared" } // shared 패키지 참조
],
"include": ["src"]
}
// 루트 tsconfig.json
{
"files": [],
"references": [
{ "path": "./packages/shared" },
{ "path": "./packages/frontend" },
{ "path": "./packages/backend" }
]
}
빌드 명령어:
# 전체 프로젝트 빌드 (참조 관계 자동 해석)
tsc --build
# 특정 프로젝트만 빌드
tsc --build packages/frontend
# 클린 빌드
tsc --build --clean
# 강제 재빌드
tsc --build --force
실제 성과 (50만 라인 모노레포):
- 빌드 전 (단일 프로젝트): 15분 22초
- 빌드 후 (프로젝트 참조): 6분 18초 (첫 빌드)
- 증분 빌드: 1분 35초
- 전체 59% 향상, 증분 90% 향상
실전 최적화 체크리스트
✅ 필수 최적화 (모든 프로젝트)
{
"compilerOptions": {
"skipLibCheck": true, // ✅ 30-50% 속도 향상
"incremental": true, // ✅ 재빌드 60-80% 향상
"moduleResolution": "bundler", // ✅ 최신 번들러 사용 시
"forceConsistentCasingInFileNames": true // ✅ 파일명 대소문자 일관성
}
}
🎯 선택적 최적화 (프로젝트 특성에 따라)
{
"compilerOptions": {
"noEmit": true, // webpack/Vite 등 사용 시
"isolatedModules": true, // Babel/esbuild 사용 시
"composite": true, // 모노레포 프로젝트 참조 시
"skipDefaultLibCheck": true // 기본 라이브러리 체크 건너뛰기
}
}
📊 성능 측정 방법
# 빌드 시간 측정
time tsc --build
# 상세한 성능 분석
tsc --diagnostics
# 타입 체크 시간 측정
tsc --noEmit --diagnostics
실제 출력 예시:
Files: 847
Lines: 167342
Identifiers: 42156
Symbols: 38967
Types: 9853
Instantiations: 52341
Memory used: 186.50MB
I/O Read: 0.15s
I/O Write: 0.00s
Parse time: 1.23s
Bind time: 0.87s
Check time: 4.56s
Emit time: 0.34s
Total time: 7.00s
분석 포인트:
- Parse time 높음: 파일이 너무 많음 → exclude 최적화
- Check time 높음: 복잡한 타입 추론 → strict 옵션 조정
- I/O Read 높음: 모듈 해석 비효율 → moduleResolution 변경
흔한 실수와 해결책
❌ 실수 1: strict 없이 시작하기
// ❌ 나쁜 예 - 나중에 고치기 어려움
{
"compilerOptions": {
"strict": false
}
}
문제점: 타입 안전성이 약해 런타임 에러 발생 확률이 높고, 나중에 strict로 전환하기 매우 어렵습니다.
해결책:
// ✅ 좋은 예 - 처음부터 strict 활성화
{
"compilerOptions": {
"strict": true
}
}
// ✅ 대안 - 점진적 활성화
{
"compilerOptions": {
"strict": false,
"noImplicitAny": true, // 먼저 any 금지부터
// 추후 strictNullChecks 등 단계적 활성화
}
}
❌ 실수 2: node_modules를 exclude에서 제외하지 않음
// ❌ 나쁜 예
{
"exclude": ["dist"]
}
문제점: node_modules의 모든 파일까지 컴파일 대상이 되어 엄청나게 느려집니다.
해결책:
// ✅ 좋은 예
{
"exclude": [
"node_modules", // ⭐ 필수
"dist",
"build",
"coverage"
]
}
❌ 실수 3: lib 옵션 과다 지정
// ❌ 나쁜 예 - 불필요한 라이브러리 추가
{
"compilerOptions": {
"lib": [
"ES5", "ES6", "ES2015", "ES2016", "ES2017",
"ES2018", "ES2019", "ES2020", "ES2021",
"DOM", "DOM.Iterable", "WebWorker"
]
}
}
문제점: 불필요한 타입 정의를 로드하여 메모리와 컴파일 시간 낭비
해결책:
// ✅ 좋은 예 - 필요한 것만 명시
{
"compilerOptions": {
"lib": ["ES2020", "DOM", "DOM.Iterable"]
}
}
❌ 실수 4: 빌드 결과물을 다시 컴파일
// ❌ 나쁜 예
{
"include": ["src", "dist"] // dist도 포함
}
문제점: 빌드된 JavaScript 파일까지 다시 컴파일 대상이 되어 무한 루프 가능
해결책:
// ✅ 좋은 예
{
"include": ["src"],
"exclude": ["dist", "build"]
}
❌ 실수 5: esModuleInterop 없이 CommonJS 모듈 import
// esModuleInterop: false일 때
import React from 'react'; // ❌ 에러!
// 해결 방법 1: * as 사용
import * as React from 'react'; // 번거로움
// 해결 방법 2: esModuleInterop 활성화
해결책:
// ✅ 좋은 예
{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}
💡 실무 활용 꿀팁
환경별 설정 분리
// tsconfig.json - 기본 설정
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
// tsconfig.dev.json - 개발용
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true, // 파일 생성 안 함 (빠름)
"incremental": true, // 증분 컴파일
"sourceMap": true // 디버깅 용이
}
}
// tsconfig.prod.json - 프로덕션용
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"declaration": true, // .d.ts 생성
"declarationMap": true,
"sourceMap": false, // 프로덕션에서는 불필요
"removeComments": true, // 주석 제거로 크기 감소
"outDir": "./dist"
}
}
// tsconfig.test.json - 테스트용
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "@testing-library/jest-dom"]
},
"include": ["src/**/*.test.ts", "src/**/*.spec.ts"]
}
package.json 스크립트 연동:
{
"scripts": {
"dev": "tsc --project tsconfig.dev.json --watch",
"build": "tsc --project tsconfig.prod.json",
"type-check": "tsc --noEmit",
"test": "jest --config jest.config.js"
}
}
TypeScript 5.9+ 최신 옵션 완전 가이드
verbatimModuleSyntax: true
효과: import/export 구문을 정확하게 유지하여 런타임 에러 방지
// verbatimModuleSyntax: true일 때
// ❌ 타입만 import하면 에러 (런타임에 없음)
import { User } from './types'; // User가 타입이면 에러
// ✅ 타입임을 명시
import type { User } from './types';
// ✅ 값과 타입을 분리
import { api } from './api';
import type { ApiResponse } from './api';
장점:
- ESM과 CommonJS 혼재 시 더 정확한 체크
- 번들러가 다른 모듈 형식으로 변환해도 안전
- import 구문의 의도를 명확히 표현
moduleDetection: "force"
효과: 모든 파일을 모듈로 처리 (전역 스크립트 방지)
// moduleDetection: "force"
// ❌ 이전: import/export 없으면 전역 스크립트로 인식
const config = { apiUrl: "..." }; // 전역 변수 오염
// ✅ 이후: 빈 export라도 추가하면 모듈로 인식
export {}; // 이 파일을 모듈로 만듦
const config = { apiUrl: "..." }; // 안전한 로컬 변수
언제 유용한가요:
- 유틸리티 파일이 의도치 않게 전역 스크립트가 되는 것 방지
- 모든 파일에서 일관된 모듈 시스템 사용
- 타입 충돌 방지
noUncheckedSideEffectImports: true
효과: 사이드 이펙트만 있는 import를 명시적으로 체크
// noUncheckedSideEffectImports: true
// ❌ 타입이 없는 패키지를 사이드 이펙트로 import하면 경고
import 'some-library'; // 타입 정의 없으면 에러
// ✅ 명시적으로 허용
import 'some-library'; // @ts-expect-error: 사이드 이펙트 전용
// ✅ 또는 타입 정의 추가
declare module 'some-library' {
export function init(): void;
}
장점:
- 타입 정의 누락된 라이브러리 사용 시 경고
- 불필요한 사이드 이펙트 import 방지
- 번들 크기 최적화
noUncheckedIndexedAccess: true
효과: 배열/객체 인덱스 접근 시 undefined 체크 강제
// noUncheckedIndexedAccess: true
const users = ['Alice', 'Bob'];
// ❌ 이전: string으로 추론 (위험!)
const user = users[2]; // 타입: string
console.log(user.toUpperCase()); // 런타임 에러!
// ✅ 이후: string | undefined로 추론
const user = users[2]; // 타입: string | undefined
if (user) {
console.log(user.toUpperCase()); // 안전!
}
실무 효과:
- 배열 인덱스 접근 버그 80% 감소
- Map, Record 타입 사용 시 안전성 향상
VSCode 설정 최적화
// .vscode/settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"typescript.preferences.importModuleSpecifier": "non-relative",
// 자동 import 경로 설정
"typescript.preferences.includePackageJsonAutoImports": "on",
// 성능 개선
"typescript.disableAutomaticTypeAcquisition": false,
"typescript.tsserver.maxTsServerMemory": 4096, // 메모리 증가
// 파일 저장 시 자동 정리
"editor.codeActionsOnSave": {
"source.organizeImports": true,
"source.fixAll": true
}
}
CI/CD 최적화
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
# TypeScript 캐싱으로 속도 향상
- name: Cache TypeScript
uses: actions/cache@v3
with:
path: |
node_modules/.cache/typescript
.tsbuildinfo
key: ${{ runner.os }}-ts-${{ hashFiles('**/tsconfig.json') }}
- name: Install dependencies
run: npm ci
- name: Type check
run: npm run type-check
프로젝트 건강도 체크 스크립트
// scripts/check-tsconfig.ts
import fs from 'fs';
import path from 'path';
interface TsConfig {
compilerOptions?: {
skipLibCheck?: boolean;
incremental?: boolean;
strict?: boolean;
moduleResolution?: string;
};
exclude?: string[];
}
function checkTsConfig() {
const configPath = path.join(process.cwd(), 'tsconfig.json');
const config: TsConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
const recommendations: string[] = [];
// 필수 최적화 체크
if (!config.compilerOptions?.skipLibCheck) {
recommendations.push('⚠️ skipLibCheck: true 권장 (30-50% 속도 향상)');
}
if (!config.compilerOptions?.incremental) {
recommendations.push('⚠️ incremental: true 권장 (재빌드 60-80% 향상)');
}
// 타입 안전성 체크
if (!config.compilerOptions?.strict) {
recommendations.push('⚠️ strict: true 권장 (타입 안전성 향상)');
}
// 모듈 해석 체크
if (config.compilerOptions?.moduleResolution !== 'bundler') {
recommendations.push('💡 moduleResolution: "bundler" 고려 (최신 번들러 사용 시)');
}
// exclude 체크
if (!config.exclude?.includes('node_modules')) {
recommendations.push('🚨 node_modules를 exclude에 추가하세요!');
}
if (recommendations.length === 0) {
console.log('✅ tsconfig.json이 최적화되어 있습니다!');
} else {
console.log('📋 tsconfig.json 개선 제안:\n');
recommendations.forEach(rec => console.log(rec));
}
}
checkTsConfig();
실행:
npx ts-node scripts/check-tsconfig.ts
자주 묻는 질문 (FAQ)
Q1: skipLibCheck: true가 안전한가요?
A: 실무에서는 99% 안전합니다. 빌드 시간을 30-50% 단축시키는 효과가 훨씬 크고 유명한 라이브러리들은 이미 충분히 검증되었어요.
Q2: strict 모드를 활성화하면 기존 코드가 다 에러가 나는데요?
A: 점진적으로 활성화하세요. noImplicitAny부터 시작해서 3-6개월에 걸쳐 단계적으로 전환하는 것이 현실적입니다.
Q3: incremental 빌드가 느려지는 경우도 있나요?
A: 전체 코드를 매번 수정하는 경우에는 캐시 오버헤드가 있지만 실무에서는 평균 60-80% 빠릅니다.
Q4: moduleResolution bundler로 바꿨더니 빌드가 안 돼요
A: TypeScript 5.0 이상에서만 지원됩니다. 이전 버전은 node16이나 nodenext를 사용하세요.
Q5: 프로젝트 참조는 언제 사용하나요?
A: 50만 라인 이상의 대규모 프로젝트나 모노레포에서 권장합니다. 첫 빌드 40-60%, 증분 빌드 80-90% 향상됩니다.
❓ tsconfig.json 최적화 마무리
tsconfig.json 최적화는 단순히 빌드 시간을 줄이는 것을 넘어 개발 경험 전체를 개선하는 핵심 작업입니다. skipLibCheck와 incremental만 활성화해도 50% 이상 빌드 시간을 단축할 수 있어요.
저도 처음에는 기본 설정으로 시작했다가 프로젝트가 커지면서 빌드가 느려져 고생했습니다. 하지만 이 글에서 소개한 최적화 전략들을 적용한 후 개발 생산성이 크게 향상되었어요. 여러분의 프로젝트에도 꼭 적용해보세요!
더 심화된 TypeScript 활용법이 궁금하시다면 TypeScript 데코레이터 완전정복 가이드도 함께 확인해보세요! 💪
🔗 TypeScript 심화 학습 시리즈
tsconfig.json 최적화를 완료했다면 다른 고급 TypeScript 기능들도 마스터해보세요:
📚 다음 단계 학습 가이드
- TypeScript 마이그레이션 전략 완전 가이드: JavaScript 프로젝트 안전하게 전환하기
- TypeScript 완전정복: 실무 타입 설계 패턴: 체계적인 타입 설계 마스터하기
- TypeScript 유틸리티 타입 실무 활용법: Pick, Omit, Record 효율적 활용하기
- TypeScript 에러 디버깅 완전 가이드: 복잡한 타입 에러 해결하기
- TypeScript 데코레이터 완전정복 가이드: 메타프로그래밍으로 생산성 극대화하기