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로 개발 편의성 확보
'개발 > Typescript' 카테고리의 다른 글
| [TYPESCRIPT] TypeORM + TypeScript 사용하기 — 엔티티부터 실무 설계까지 (0) | 2025.12.29 |
|---|---|
| [TYPESCRIPT] NestJS에서 TypeScript 활용하기 — “타입을 설계의 중심”으로 가져오는 실무 패턴 (0) | 2025.12.28 |
| [TYPESCRIPT] Axios와 함께 쓰는 TypeScript — API 호출을 타입으로 통제하는 실무 패턴 (0) | 2025.12.26 |
| [TYPESCRIPT] 타입 안전한 API 응답 처리하기 - 런타임 오류를 컴파일 단계에서 차단하는 설계 (0) | 2025.12.25 |
| [TYPESCRIPT] TypeScript에서 JSON 다루기 - 타입 안정성으로 런타임 오류 줄이기 (0) | 2025.12.24 |
