티스토리 뷰

TypeScript 구조 설계를 이미지화 하였다.

 

 타입스크립트는 자바스크립트의 단점을 보완하기 위해 등장한 정적 타입 기반 언어입니다. 자바스크립트와 호환되며 강력한 타입 시스템을 제공해 대규모 애플리케이션 개발 시 안정성과 가독성을 높여주는 장점이 있습니다. 하지만 타입스크립트를 도입한다고 해서 모든 문제가 자동으로 해결되는 것은 아닙니다. 실무에서는 코드 품질뿐 아니라, 프로젝트의 구조 자체가 효율성과 유지보수성에 큰 영향을 미치기 때문입니다.

 

 본 글에서는 타입스크립트 프로젝트를 어떻게 구조화하고 설계하면 실무에서 효과적일지에 대해 구체적으로 안내합니다. 프런트엔드, 백엔드, 전체 스택을 막론하고 공통적으로 적용 가능한 전략을 중심으로 소개합니다.

모듈화 된 디렉터리 구조 설계

 타입스크립트 프로젝트를 체계적으로 설계하려면 먼저 디렉터리 구조를 어떻게 구성할 것인지부터 결정해야 합니다. 특히 프로젝트가 커질수록 모듈화 된 구조를 갖추는 것이 중요합니다. 모듈화란 기능, 역할, 책임 단위로 폴더와 파일을 나누는 전략입니다.

 가장 많이 사용되는 기본 구조는 다음과 같습니다:

src/
├── common/           # 공통 모듈 (에러처리, 응답 포맷 등)
├── config/           # 환경설정 관련
├── controllers/      # 라우터 처리 담당
├── services/         # 비즈니스 로직
├── models/           # 데이터 모델 및 DB 처리
├── interfaces/       # 인터페이스 및 타입 정의
├── dtos/             # 요청 및 응답 스펙 정의
├── utils/            # 유틸 함수 모음
├── middlewares/      # 미들웨어 로직
└── main.ts           # 엔트리 포인트

 

 이 구조는 백엔드(Node.js, NestJS)든 프론트엔드(React, Next.js)든 동일하게 적용할 수 있으며, 규모에 따라 하위 폴더를 기능별로 나누는 것도 좋습니다. 예를 들어 `src/features/users` 폴더 아래에 `user.controller.ts`, `user.service.ts`, `user.dto.ts`를 함께 배치하면 하나의 기능을 중심으로 모든 요소가 모이므로 유지보수와 테스트가 훨씬 수월합니다.

 또한 폴더 및 파일 네이밍 컨벤션도 중요합니다. 일반적으로는 camelCase 또는 kebab-case 중 하나로 일관성을 유지하고, 각 모듈의 `index.ts` 파일을 통해 내부 요소를 export 하여 외부 접근 시 경로를 단순화할 수 있습니다.

TSConfig와 절대경로 설정

 프로젝트가 커질수록 상대 경로를 계속 사용하는 것은 유지보수에 불리합니다. 예를 들어 `import { getUser } from '../../../../services/users'`와 같은 코드는 한눈에 어떤 모듈인지 파악하기 어렵고, 디렉터리 구조가 바뀌면 수많은 경로를 일일이 수정해야 합니다.

이런 문제를 해결하기 위해 `tsconfig.json`의 `paths` 옵션을 활용한 절대 경로 설정이 필수입니다. 다음과 같은 설정 예제를 살펴보겠습니다:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@controllers/*": ["controllers/*"],
      "@services/*": ["services/*"],
      "@models/*": ["models/*"],
      "@utils/*": ["utils/*"],
      "@config/*": ["config/*"]
    }
  }
}

 

 이렇게 설정하면 `import { UserService } from '@services/users'` 와 같이 간단하고 직관적인 경로를 사용할 수 있습니다. 실제로 많은 기업들이 `@` prefix를 붙여 루트 디렉토리를 지정하고 있습니다. 절대 경로 설정은 개발 생산성을 높이는 것뿐 아니라 코드리딩, 협업, 리팩토링을 훨씬 쉽게 만들어 줍니다.

 또한 `tsconfig`에서 반드시 챙겨야 할 옵션은 다음과 같습니다:

  • "strict": true – 타입 안정성을 극대화
  • "esModuleInterop": true – 모듈 호환성 확보
  • "resolveJsonModule": true – JSON 파일 import 가능
  • "noImplicitAny": true – 암시적 any 타입 방지

 이 외에도 컴파일 결과물을 관리하기 위한 `outDir`, `rootDir`, `include`, `exclude` 옵션은 CI/CD 연동 시에도 큰 도움이 됩니다.

 예를 들어 `src`는 개발용, `dist`는 빌드용으로 분리하고 Git에선 `dist`를 무시하도록 `.gitignore`에 명시해야 합니다.

의존성 관리 및 공통 모듈 분리 전략

 구조 설계의 완성은 의존성 설계에 달려 있습니다. 각 기능 모듈이 서로 과도하게 의존하지 않도록 느슨한 결합을 지향해야 하고, 공통 코드나 중복되는 코드는 반드시 분리하여 재사용할 수 있도록 해야 합니다.

 예를 들어 다음과 같은 디렉토리 구분은 많은 기업에서 공통적으로 사용됩니다:

  • src/utils: 로깅, 날짜 포맷, 암호화 등 유틸 함수
  • src/constants: 앱 전역에서 사용하는 상수값
  • src/types: 글로벌 인터페이스 및 타입
  • src/common: 에러 처리, API 응답 포맷 처리

 이렇게 분리하면 특정 모듈에만 종속되지 않으므로 코드 재사용성과 유지보수성이 크게 향상됩니다. 또한 의존성 주입(Dependency Injection) 패턴을 적극 활용하면 각 모듈이 직접 서로를 참조하지 않고도 유기적으로 연결될 수 있습니다.

 예를 들어 NestJS 같은 프레임워크는 DI 패턴을 내장하고 있으며, 모듈 단위로 서비스를 주입받아 테스트 용이성과 확장성을 확보할 수 있습니다. 이와 함께 단위 테스트를 고려한 설계를 하려면 각 서비스의 인터페이스를 먼저 정의하고 구현체는 별도로 나누는 방식이 좋습니다.

 마지막으로 코드 스타일 통일도 중요한 설계 요소입니다. 아래 도구들은 팀의 코드 품질과 협업 생산성을 크게 높여줍니다:

  • ESLint: 문법 및 코드 규칙 검사
  • Prettier: 코드 포맷 자동 정리
  • Husky + lint-staged: 커밋 전 자동 검사
  • Commitlint: 커밋 메시지 형식 강제

 이런 도구를 설정해두면 실수로 잘못된 코드가 커밋되는 것을 방지하고, 누구나 동일한 구조와 컨벤션을 따르게 되어 유지보수 비용이 줄어듭니다. 장기적으로 봤을 때 구조 설계 못지않게 중요한 요소입니다.

 

 요약하자면, 코드 구조를 잘 설계하는 것은 단지 폴더를 나누는 것을 넘어서서 전체 개발 흐름과 협업 문화에 영향을 주는 중요한 작업입니다. 초기부터 잘 설계된 구조는 팀의 생산성과 프로젝트의 성공을 좌우할 수 있습니다.

 

 타입스크립트의 강점을 극대화하려면 단순히 문법을 익히는 데 그치지 않고, 구조 설계 단계부터 체계적으로 접근해야 합니다. 디렉터리 구성, tsconfig 설정, 의존성 관리, 도구 세팅까지 세심하게 설계하면 개발 생산성과 유지보수 효율성이 크게 향상됩니다. 지금 바로 여러분의 프로젝트에 이 구조를 도입해 보세요!

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함