[TYPESCRIPT] TypeScript + Express 프로젝트 설정하기

 

Express는 Node.js 기반 웹 서버를 빠르게 만들 수 있는 대표적인 프레임워크입니다. 여기에 TypeScript를 붙이면 개발 생산성과 안정성이 크게 올라가지만, 초기 설정을 대충 해두면 빌드/실행 분리, 경로(alias), 타입 설정, 개발 서버 재시작에서 계속 발목을 잡힙니다.

처음부터 실무형 을 목표로, TypeScript + Express 프로젝트를 깔끔하게 세팅하는 방법을 정리해 보았습니다.

 

프로젝트 생성 및 패키지 설치

먼저 디렉토리를 만들고 초기화합니다.

mkdir ts-express-api
cd ts-express-api
npm init -y

필수 패키지를 설치합니다.

npm i express
npm i -D typescript ts-node-dev @types/node @types/express
  • typescript : 컴파일러
  • ts-node-dev : 개발 중 자동 재시작
  • @types/* : 타입 정의

 

tsconfig.json 생성 (실무 권장 옵션)

다음 명령으로 tsconfig를 생성합니다.

npx tsc --init

실무에서 자주 사용하는 옵션 중심으로 최소한만 정리하면 다음과 같습니다.

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "moduleResolution": "Node",
    "outDir": "dist",
    "rootDir": "src",

    "strict": true,
    "noImplicitAny": true,
    "esModuleInterop": true,

    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "dist"]
}

포인트는 다음입니다.

  • rootDir / outDir로 소스와 빌드 결과 분리
  • strict로 타입 안정성 확보
  • esModuleInterop로 Express import 호환성 개선

 

기본 폴더 구조 만들기

가장 단순하면서도 확장 가능한 구조는 아래 형태입니다.

src/
  app.ts
  server.ts
  routes/
    health.ts

 

Express 앱 구성 (app.ts)

import express from "express";
import healthRouter from "./routes/health";

const app = express();

app.use(express.json());
app.use("/health", healthRouter);

export default app;

app.ts는 “Express 앱 구성만” 담당하게 분리해두면 테스트 작성과 확장이 훨씬 편해집니다.

 

서버 엔트리 포인트 (server.ts)

import app from "./app";

const PORT = Number(process.env.PORT) || 3000;

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

엔트리 포인트를 분리하는 이유는 간단합니다.

  • app만 따로 import해서 테스트 가능
  • 서버 실행 로직을 분리해 책임이 명확

 

라우터 예시 (routes/health.ts)

import { Router } from "express";

const router = Router();

router.get("/", (req, res) => {
  res.json({ ok: true });
});

export default router;

Health check는 운영 환경에서도 항상 필요하므로 프로젝트 시작 단계에서 넣어두는 것을 권장합니다.

 

package.json 스크립트 구성

개발/배포 환경을 분리하는 스크립트를 구성합니다.

{
  "scripts": {
    "dev": "ts-node-dev --respawn --transpile-only src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js"
  }
}
  • dev : 개발 서버 (자동 재시작)
  • build : TypeScript 컴파일
  • start : 빌드 결과 실행

 

실행 확인

개발 서버를 실행합니다.

npm run dev

그리고 다음 URL을 호출해 확인합니다.

curl http://localhost:3000/health

정상이라면 아래와 같은 JSON이 출력됩니다.

{ "ok": true }

 

실무에서 추가로 자주 붙이는 것들

여기까지가 “최소 구성”이고, 실무에서는 보통 아래를 추가합니다.

  • 환경변수 관리 : dotenv
  • 로그 : pino / winston
  • 에러 핸들링 미들웨어
  • 요청 검증 : zod / joi
  • 테스트 : jest + supertest

이 부분은 다음 글에서 “프로덕션급 Express 템플릿” 형태로 확장해보겠습니다.

 


 

TypeScript + Express 프로젝트의 핵심은 개발 실행(dev)과 배포 실행(build/start)을 분리하고, app과 server를 분리해서 테스트/확장성을 확보하는 것입니다.

  • tsconfig에서 rootDir/outDir 정리
  • app.ts / server.ts 분리
  • ts-node-dev로 개발 편의성 확보