개요

tsconfig.json은 TypeScript 컴파일러 tsc의 설정 파일이며 프로젝트를 어떻게 컴파일할지 정의함

TypeScript 코드가 JavaScript로 변환되는 경로에 대한 스위치 보드 역할 수행

TypeScript (.ts)
    [ tsc ]  ← tsconfig.json이 규칙 제공
JavaScript (.js)

module 옵션

출력되는 JavaScript의 모듈 시스템 선택

모듈 시스템의 변화 요약

  • 없음, 전역 스코프 공유
  • CommonJS, require/module.exports 중심
  • AMD, 브라우저 환경 define/require
  • ES Modules, 표준 import/export

주요 값과 용도

  • commonjs Node.js 구버전 호환
  • es2015/es6 표준 ESM, 브라우저·번들러 환경
  • es2020 ESM + dynamic import 사용 환경
  • es2022 ESM + top-level await 사용 환경
  • esnext 최신 ESM 기능 추적
  • nodenext Node.js 16+의 ESM 출력·해석 규칙 반영
  • node16 Node.js 16의 ESM과 CJS 혼합 환경 대응

같은 코드의 다른 출력 예시

// 원본 TypeScript
import { foo } from './utils'
export const bar = foo + 1

module: “commonjs” 출력

"use strict"
Object.defineProperty(exports, "__esModule", { value: true })
const utils_1 = require("./utils")
exports.bar = utils_1.foo + 1

module: “es2015” 출력

import { foo } from './utils'
export const bar = foo + 1

moduleResolution 옵션

import 경로를 어떻게 찾을지 결정하는 규칙이며 module과 함께 설계하는 것이 안전함

import { foo } from './utils'
//                   ↑ 이 경로를 어떤 규칙으로 해석할지 선택

주요 값과 짝

  • node Node.js CommonJS 해석 규칙, module: commonjs와 궁합
  • node16 Node.js 16 ESM 규칙, module: node16과 궁합
  • nodenext 최신 Node.js ESM 규칙, module: nodenext와 궁합
  • bundler 번들러의 해석 규칙 가정, Vite·Webpack 등과 사용
  • classic TypeScript 1.x 규칙, 신규 프로젝트 비권장

node와 nodenext의 차이 핵심

node

  • 확장자 생략 허용, ./utils.ts 또는 ./utils/index.ts 탐색
  • package.json의 main 필드 우선 사용

nodenext

  • ESM 표준 준수, import 시 확장자 명시 요구되는 환경
  • TypeScript 소스가 .ts여도 import는 .js로 작성, 런타임 기준 경로이기 때문
  • package.json의 exports 필드 사용
// 소스: ./utils.ts
// 컴파일 후: ./utils.js
// import 경로는 빌드 산출물 기준으로 작성
import { foo } from './utils.js'

권장 조합

환경별 안전한 조합 안내

  • Node.js 16+ module: nodenext, moduleResolution: nodenext
  • Node.js 구버전 module: commonjs, moduleResolution: node
  • Vite/Webpack module: esnext, moduleResolution: bundler
  • 브라우저 직접 로딩 module: es2022, moduleResolution: bundler

예시 설정 해석

{
  "module": "nodenext",
  "moduleResolution": "nodenext"
}

의미

  • Node.js 16+ 환경에서 ESM 방식으로 출력 및 해석
  • import 경로에 확장자 명시 필요, 보통 .js로 작성
  • package.json의 exports 필드 기반 해석 지원
  • 최신 Node.js 표준 흐름을 따름

기타 주요 옵션

target

  • 출력 JavaScript 문법 수준을 지정
  • 예시
"target": "es2022"
  • es5 IE 호환 레벨, var/function 중심
  • es6/es2015 let/const, arrow function, class
  • es2017 async/await
  • es2020 optional chaining와 nullish coalescing 포함
  • es2022 top-level await, class fields
  • esnext 최신 사양 추적, 빌드 타깃 환경에 따라 주의 필요

declaration

  • .d.ts 타입 선언 파일 생성 여부
  • 라이브러리 배포 시 필수에 가까움
"declaration": true

experimentalDecorators 및 emitDecoratorMetadata

  • 사용자 데코레이터 사용과 메타데이터 방출 제어
  • reflect-metadata 의존 생태계에서 필요
"experimentalDecorators": true,
"emitDecoratorMetadata": true

baseUrl

  • 상대경로 해소 기준 디렉터리 지정
"baseUrl": "./"

paths

  • 경로 별칭 정의, baseUrl과 함께 사용
"baseUrl": "./",
"paths": {
  "@/*": ["src/*"]
}

strict 계열

  • strict를 true로 설정하면 아래 엄격 옵션 일괄 활성화
  • 세부 예시
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false

skipLibCheck

  • node_modules 내 .d.ts 타입 체크 스킵으로 빌드 성능 개선
"skipLibCheck": true

sourceMap

  • 디버깅을 위한 소스맵 생성
"sourceMap": true

allowSyntheticDefaultImports

  • default export가 없는 모듈에 대해 default import 허용
  • 타입 체크에만 영향, 출력 코드에는 영향 없음

incremental

  • 증분 빌드 활성화로 재컴파일 시간 단축

전체 tsconfig 해석

아래는 Node.js 16+ ESM 환경을 가정한 구성 예시

{
  "compilerOptions": {
    // 모듈 시스템
    "module": "nodenext",           // Node.js ESM 출력
    "moduleResolution": "nodenext", // Node.js ESM import 해석

    // 출력 설정
    "target": "es2022",            // ES2022 문법 사용
    "outDir": "./dist",            // 출력 폴더
    "declaration": true,           // .d.ts 생성
    "sourceMap": true,             // 소스맵 생성
    "removeComments": true,        // 주석 제거

    // 데코레이터 사용
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,

    // import 관련
    "baseUrl": "./",
    "allowSyntheticDefaultImports": true,

    // 성능
    "incremental": true,
    "skipLibCheck": true,

    // 타입 체크 예시, 필요 시 엄격 모드 권장
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  }
}

요약

핵심 옵션과 역할 정리

  • module 출력 JS 모듈 문법 선택, require와 import 중 무엇을 낼지 정의
  • moduleResolution import 경로 해석 규칙, Node 해석 규칙 또는 번들러 가정 선택
  • target 출력 JS 문법 수준, 배포 대상 런타임과 일치 필요
  • strict* 타입 체크 엄격도, 팀 기준에 따라 일괄 적용 권장

nodenext는 최신 Node.js ESM 표준을 따른다는 의미이며, 확장자 명시와 exports 기반 해석이 전제됨

마무리

빌드 타깃과 런타임 해석 규칙이 맞아야 런타임 오류가 줄어듦 module과 moduleResolution을 먼저 결정한 뒤 baseUrl, paths, strict, declaration 등 후속 옵션을 정합성 있게 조정하는 흐름 권장 ESM 전환 중이라면 nodenext 조합과 확장자 명시 원칙을 팀 규칙으로 고정하는 것이 안전함

참고자료