[TypeScript] TS Config, ES Lint --> 런타임 장애를 막는 안전한 방법

2026. 3. 25. 11:19·Language/TypeScript

"조직의 개발 문화와 배포 파이프라인의 안정성을 근본적으로 끌어올리는 아키텍처 설계도란 .."

 

미래에 있을 장애를 조기에 예방하려면 ..

시스템 레벨의 관점(릴리스 엔지니어링, 점진적 롤아웃, 장애 예방)에서 고민해 볼 필요가 있을 것 같다고 생각합니다.



 

다중 레포지토리(Polyrepo) 정적 분석 환경 표준화 및 점진적 도입기입니다 !!

 

1. 들어가며: "왜 레포지토리마다 코드 리뷰 기준이 다를까 ?"

현재 팀의 백엔드 시스템은 역할에 따라 여러 개의 레포지토리(API 서버, 게이트웨이, 서버리스 함수 등)로 나뉘어 서비스되고 있습니다.

어느 날 신규 피처를 개발하며 여러 레포지토리를 오가던 중, 한 가지 의문이 생겼습니다.

 

"A 서비스에서는 에러를 뱉는 코드가, 왜 B 서비스에서는 정상적으로 통과되어 배포되고 있었던 걸까 ..?"

 

레포지토리마다 TypeScript의 strict 옵션 활성화 여부가 달랐고,

어떤 곳은 구형 린터(TSLint)가 남아있었으며, Prettier 포맷팅 기준도 파편화되어 있었습니다.

 

이는 단순히 '코드가 안 예쁘다'의 문제가 아니었습니다.

타입 검사가 느슨한 곳에서는 Cannot read properties of undefined와 같은 런타임 에러가 발생할 위험이 배포 단계까지 방치되고 있었습니다.

"정적 분석 표준화는 단순한 스타일 통일이 아니라, 릴리스 엔지니어링이자 장애 예방 작업이다 .."라는 생각으로,

백엔드 정적 분석 환경 통합 작업에 들었습니다.



2. 문제 정의: 무엇이 진짜 문제인가 ?

초기에는 단순히 "모든 레포지토리의 tsconfig에 strict: true를 켜면 되는 것 아닐까 ?"라고 생각했습니다.

하지만 상황을 깊이 분석해보니 세 가지 큰 리스크가 있었습니다.

  1. 배포 리스크 (런타임 영향): 컴파일러 옵션(target, module 등)을 한 번에 통일하면, 빌드 산출물(JS)이 변경되어 예상치 못한 프로덕션 장애가 발생할 수 있습니다.
  2. 개발자 경험(DX) 저하: 수년간 누적된 레거시 코드에 갑자기 엄격한 룰을 들이밀면, 수천 개의 에러 폭탄이 떨어져 팀원들의 피로도만 높아질 것입니다.
  3. 품질 게이트의 부재: 로컬이나 PR 단계에서 린트/타입 에러를 강제(Blocking)하지 않아, 결국 배포 파이프라인(CI/CD) 과정에서 뒤늦게 빌드가 터지는 병목이 존재했습니다.

따라서 목표를 수정했습니다. "기존 코드를 한 번에 깨지 않으면서, 신규 코드부터 안전하고 점진적으로 표준을 강제해 보자 .."



3. 해결 전략: 가장 안전하고 확실한 롤아웃(Rollout)

전략 1. 단일 진실 공급원 (Centralized Config Package) 구축

각 레포지토리에 .eslintrc나 tsconfig.json을 복붙하는 방식은 언젠가 다시 파편화를 유발합니다. 이를 방지하기 위해 사내 공통 패키지(@company/tsconfig, @company/eslint-config)를 구축했습니다.

단, 모든 서비스의 런타임 환경(NestJS, Serverless 등)이 다르므로, 공통 Base 설정 위에 각 환경에 맞는 Profile을 상속받아 쓸 수 있도록 유연하게 설계했습니다.

전략 2. Build와 Quality Check의 분리 (핵심)

이 프로젝트에서 가장 중요하게 생각한 부분입니다. 컴파일 타임의 '타입 검증'과 '실제 빌드 산출물 생성'을 분리했습니다.

  • tsconfig.build.json : 실제 JS로 변환하고 배포 산출물을 만드는 용도 (기존 설정 유지)
  • tsconfig.typecheck.json : --noEmit 옵션을 사용해 오직 타입의 엄격성만 검사하는 용도 (신규 표준 적용)

이렇게 분리한 덕분에, 실제 프로덕션에 배포되는 코드의 런타임 리스크를 0으로 통제하면서 타입 검증만 안전하게 고도화할 수 있었습니다.

전략 3. 점진적 강제화 (Progressive Rollout)

팀원들이 에러 폭탄에 압도되지 않도록, 다음과 같은 단계적 롤아웃 파이프라인을 설계했습니다.

  1. 로컬 방어 (Husky + lint-staged): 커밋 시점에 개발자가 수정한 파일만 자동으로 포맷팅하고 린트를 돌려 기계적인 수정의 수고를 덜고자 했습니다.
  2. PR 단계 - 변경 파일 검증 (Changed-file Gate): CI에서 전체 코드가 아닌, '이번 PR에서 신규/수정된 파일'에 대해서만 엄격한 타입/린트 검사를 통과(Blocking)하도록 강제했습니다.
  3. PR 단계 - 전체 검증 관찰 (Advisory): 레거시 전체에 대한 검사는 CI를 실패시키지 않되(Continue-on-error), 에러 카운트 추세만 관찰하여 부채가 줄어드는지 트래킹했습니다.



4. 적용 및 성과

이러한 전략을 바탕으로 가장 설정이 모던한 레포지토리부터 파일럿을 적용했고, 점진적으로 레거시 의존성이 높은 코어 API 서버까지 확산해 나가는 로드맵을 실행 중입니다.

이 작업을 통해 우리 팀은 다음과 같은 변화를 얻게 되었습니다.

  • 리뷰 비용 감소: 스타일이나 사소한 타입 실수에 대한 논쟁이 사라지고, 비즈니스 로직 자체에 집중하는 코드 리뷰가 가능해졌습니다.
  • 배포 안정성 확보: Cannot read properties of undefined 같은 런타임 에러 유발 코드나, 비동기 Promise 미처리(no-floating-promises) 등을 PR 단계에서 CI가 차단하게 되었습니다.
  • 온보딩 효율화: 신규 서비스를 띄울 때 기존 설정을 복붙할 필요 없이 공통 템플릿과 패키지만 주입하면 즉시 표준 환경이 세팅됩니다.



5. 회고: 시스템을 바꾸는 것은 결국 '변화 관리'다.

처음에는 이 작업이 단순한 '정적 분석 툴 세팅'이라고 생각했습니다.

하지만 실제로 프로젝트를 기획하고 실행해 보니,

이는 "PR 게이트, 배포 파이프라인, 그리고 팀의 개발 문화를 하나의 방향으로 정렬하는 일"이었습니다.

"오늘부터 룰을 엄격하게 바꿉니다 !"라고 선언하는 것은 쉽겠죠.

하지만 진짜 엔지니어링은

기존 시스템이 망가지지 않게 보호하면서, 동료 개발자들이 피로감을 느끼지 않고 자연스럽게 새 표준에 스며들도록 안전망을 설계하는 것

도 포함한다는 것을 .. 배웠습니다 ..

 

앞으로도 단순히 코드를 짜는 것을 넘어, 팀의 생산성을 높이고

시스템의 런타임 안정성을 사전에 방어하는 인프라 레벨의 고민을 계속해 나가고 싶네요.



"다중 레포지토리 환경에서 런타임 리스크 없이 정적 분석 도구(TS/ESLint) 통합,
CI 파이프라인을 개선하여 장애율 감소 및 개발 생산성 향상"

 

 

 

 

'Language > TypeScript' 카테고리의 다른 글

[TypeScript] 타입스크립트를 공부해 보자 ..  (0) 2026.01.26
'Language/TypeScript' 카테고리의 다른 글
  • [TypeScript] 타입스크립트를 공부해 보자 ..
하가네
하가네
  • 하가네
    하 렌
    하가네
  • 전체
    오늘
    어제
    • 분류 전체보기 (127)
      • Computer Science (23)
        • 운영체제 (7)
        • 데이터통신 (6)
        • 자료구조 (4)
        • 논리회로 (0)
        • 확률 및 통계 (0)
        • 데이터베이스 (2)
        • AI소프트웨어 (3)
        • 컴퓨터네트워크 (1)
      • Design (4)
        • OOP - 객체 지향 프로그래밍 (2)
        • DDD - 도메인 주도 개발 (데이터베이스 주도 .. (0)
        • EDA - 이벤트 기반 아키텍처 (1)
        • MSA - 마이크로서비스 아키텍처 (0)
        • ADD - AI 주도 개발 (1)
      • Language (2)
        • Java (0)
        • TypeScript (2)
      • Framework (12)
        • Spring (9)
        • NestJS (3)
      • Engine (3)
        • Elasticsearch (1)
        • GraphQL + Apollo Federation (2)
      • Plugin - Extension (1)
        • VS Code (1)
        • IntelliJ (0)
      • Tips (2)
        • 터미널 명령어 (1)
        • 우분투 명령어 에러 (1)
      • SSA (26)
        • Front (1)
        • Back (23)
        • DB (1)
        • 기획 (1)
      • CNU SW 아카데미 (42)
        • 1주차 (5)
        • 2주차 (5)
        • 3주차 (2)
        • 4주차 (1)
        • 5주차 (3)
        • 6주차 (2)
        • 7주차 (0)
        • 8주차 (1)
        • 9주차 (14)
        • 10주차 (0)
        • 11주차 (1)
        • 12주차 (0)
        • 13주차 (2)
        • 14주차 (2)
        • 15주차(최종 프로젝트) (3)
        • 최종 프로젝트 이후 (1)
      • 모각코 (6)
        • 2023 동계 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    생산성
    릴리스엔지니어링
    ci/cd
    개발자경험(DX)
    Typescript
    ESLint
    아키텍처
    프론트엔드/백엔드
    DX(DeveloperExperience)
    lint-staged
    Husky
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.
하가네
[TypeScript] TS Config, ES Lint --> 런타임 장애를 막는 안전한 방법
상단으로

티스토리툴바