안녕하세요, 이상혁입니다

런타임은 가라, 빌드타임이 왔다! - FE 공통코드의 화려한 변신

런타임은 가라, 빌드타임이 왔다! - FE 공통코드의 화려한 변신

2025년 5월 23일

도입 배경

입사 초기, 사내 공통 코드(Common Code) 시스템을 도입했다. 여러 업무 도메인과 프로젝트 서비스에서 공통적으로 사용하는 의미 있는 상수값들을 프론트엔드, 백엔드, 기획/운영 담당자들이 일관되게 쓸 수 있도록 만든 체계다.

공통 코드는 개발자가 자주 사용하는 도메인 용어나 문구를 식별해서, 프론트와 백엔드 개발자들이 합의한 뒤 그룹 코드로 생성하거나 수정, 삭제한다. 이 코드들은 사내 DB에서 관리되고, 프론트에서는 API로 가져와서 라디오 버튼이나 체크박스 같은 UI 요소 표시나 데이터 값으로 사용한다.

common code change 5

도입 효과

사실 라디오 버튼이나 체크박스의 텍스트와 값을 코드에 그냥 하드코딩해도 당장은 문제 없다. 하지만 공통 코드를 도입한 덕분에 이런 장점들이 생겼다:

  1. 코드 변경 사항을 한 번에 관리할 수 있었다
  2. 다른 팀과 협업할 때 변경 내용을 즉시 공유할 수 있었다
  3. 코드 재사용성이 좋아졌다

발생한 문제점

1년 넘게 사용하다 보니, 프로젝트가 커지면서 몇 가지 불편한 점이 생겼다.

  • API로 공통 코드를 불러오다 보니, 항상 Fallback UI를 고려해야 했다.

네트워크 지연 때문에 화면이 비어 보이는 경우가 많았고, Skeleton이나 Progress Bar 같은 로딩 UI를 쓰긴 했지만 라디오 버튼 같은 입력 UI에서는 네트워크 오류가 나면 입력 자체가 불가능해지는 문제도 있었다. 단순한 정보 표시도 개발 피로도가 높아졌다.

common code change 3

  • 코드 분기 처리를 할 땐 여전히 하드코딩이 필요한 경우가 있었고, 그룹 코드명을 확인하려면 매번 Swagger나 API 응답을 확인해야 했다.
  • 공통 코드가 변경됐는지 코드 레벨에서 바로 알 수 있는 방법이 없었다.

common code change 4

개선 방향 & 방법

지금까지의 문제를 해결하면서도, 공통 코드의 핵심 목적은 그대로 유지하고 싶었다. 여러 프로젝트에서 용어를 일관되게 쓰고, 반복되는 코드 없이 효율적으로 관리하는 구조는 분명히 필요했기 때문이다.

처음에는 네트워크 캐시를 활용해서 공통 코드를 빠르게 불러오는 방식으로 시도했다. 이 방법은 UI를 빠르게 그리는 데엔 어느 정도 효과가 있었지만, 여전히 API에 의존해야 했고, 개발자 입장에선 매번 코드 값을 Swagger나 응답값을 통해 확인해야 하는 번거로움이 있었다. 무엇보다, 공통 코드가 바뀌었는지 확인하기도 어렵고, 단순한 입력 UI 하나 구현할 때도 네트워크 상태를 고려해야 하는 점은 큰 부담이었다.

결국 방향을 바꿨다. 런타임에 공통 코드를 불러오는 방식 대신, 빌드 타임에 코드로 포함시키는 구조로 전환했다.

common code change 7

처음에는 API 응답을 그대로 가져와 as const로 선언해보기도 했지만, 대부분 배열 형태로 제공되는 구조라 TypeScript가 내부 값을 제대로 추론하지 못했다. 자동완성도 불안정했고, 타입 안정성도 만족스럽지 않았다.

common code change 6

그래서 JSON 데이터를 객체 형태로 변환해주는 스크립트를 새로 만들었다. 객체 기반 구조로 바꾸니 타입 추론이 훨씬 잘 작동했고, 코드 내에서 값이나 키를 쉽게 확인할 수 있었다. 이제는 공통 코드에 변경 사항이 생기면, 백엔드에서 공유받은 JSON을 기준으로 스크립트를 한 번 돌리기만 하면 된다.

기존 유틸 함수와 타입들도 새 구조에 맞춰 정리했다. 이 방식으로 다음과 같은 점들을 개선할 수 있었다.

  • 로딩 UI 없이도 초기 화면에 공통 코드 반영 가능
  • 타입 자동완성 지원
  • 코드 안에서 직접 키나 값을 확인 가능
  • 코드 변경 이력을 Git으로 바로 확인 가능

런타임의 복잡함을 줄이고, 빌드 타임에서 모든 걸 해결하면서 작업 흐름이 훨씬 단순해졌다.

느낀점

이번 작업을 하면서 데이터 구조가 타입 추론에 얼마나 큰 영향을 미치는지 체감했다. 배열보다 객체가 타입 안정성과 개발자 경험 측면에서 훨씬 낫다. 그리고 빌드 타임과 런타임의 역할을 분리하니까, 성능과 유지보수성도 동시에 챙길 수 있었다. 이런 개선 작업은 단순한 코드 수정이 아니라 시스템 전체 품질을 높이는 중요한 과정이라는 걸 다시 느꼈다.