Skip to content
프론트엔드 코드 품질을 어떻게 올릴 수 있을까

29 Apr 2025 · 4 min read

프론트엔드 코드 품질을 어떻게 올릴 수 있을까

변경하기 쉬운 프론트엔드 코드를 위한 지침서

Frontend

이번 글은 Toss Frontend Fundamentals 문서를 읽으며 정리한 내용을 기록한 글이다.

정리 과정에서 특히 아래 글/자료들이 인사이트를 주었다:

단순 요약보다는, 실제로 내 코드에 적용해보며 느꼈던 고민 중심으로 풀어본다.

💡 코드 품질을 판단하는 네 가지 기준

토스에서는 코드 품질을 판단할 때 다음 네 가지를 핵심으로 본다:

가독성: 얼마나 쉽게 읽히는가?

예측 가능성: 이름만 보고도 어떻게 동작할지 알 수 있는가?

응집도: 관련된 것들이 가까이 모여 있는가?

결합도: 불필요하게 많은 맥락이 엮여 있지는 않은가?

1. 가독성 – 코드는 결국 '읽는 사람'을 위한 것

같이 실행되지 않는 코드는 같이 안 보이게 하기

  • 조건문이나 분기 로직은 분리해서 읽는 맥락을 줄이자
  • 예: if 안에 JSX 넣는 것보다, 조건에 이름을 붙여 위로 올리는 게 읽기 쉬움
// Before
{isLoggedIn && user.isAdmin && <AdminDashboard />}

// After
const shouldShowAdmin = isLoggedIn && user.isAdmin;

{shouldShowAdmin && <AdminDashboard />}

구현 상세 추상화 (HOC vs Wrapper)

  • HOC: 로직 재사용에 유리. 추상화되어 있으므로 구조 파악은 어렵지만 깔끔함
  • Wrapper: JSX 구조에 드러나므로 흐름이 명확함
  • 목적에 따라 선택. UI 흐름 중심이면 Wrapper, 비즈니스 로직이면 HOC가 자연스러움

선언형 코드도 '적절한 수준'이 중요함

  • 무조건 추상화하면 유지보수에 오히려 독이 됨
  • SignUpForm 예시처럼 다양한 변형이 필요한 컴포넌트는 추상화보다 명시적 표현이 낫다

복잡한 조건엔 이름을 붙이자

  • isEmpty, shouldShowTooltip, isUnauthorizedUser처럼 이름을 붙이면 코드 이해도가 확 올라감
  • 조건 렌더링도 if (조건) return null → if (shouldSkipRender) 같은 식으로 바꾸면 한눈에 읽힘

매직 넘버 없애기

  • 300, 24 * 60 * 60 * 1000 같은 값은 상수로 추출해서 의미를 드러내자
  • TIME_MS.DEBOUNCE.SEARCH, FIVE_MINUTES 식으로 쓰면 나중에 고칠 때도 훨씬 쉬움

위에서 아래로 읽히는 구조로 정리

  • 에러 메시지, 조건 로직은 상단에서 미리 분리해서 정의
  • 하나의 흐름이 위→아래로 떨어지게 하면 훨씬 덜 헷갈림

2. 예측 가능성 – 코드를 보며 '예상'할 수 있어야 한다

이름 겹치지 않게 관리하기

  • 같은 이름(http)을 여러 레벨에서 쓰면 혼란
  • httpService, httpLibrary처럼 역할이 드러나게 구분하자

같은 훅은 같은 구조로 반환하기

  • useQuery로 만든 훅은 query 객체를 반환하는 걸 팀 규칙으로 정하면 예측이 쉬움

Discriminated Union으로 유효성 검사 구조화하기

// 타입
{ ok: true } | { ok: false; reason: string }
  • 이렇게 해두면 조건 분기 시 타입이 자동으로 좁혀지고 실수 방지됨
  • Basarat 글 참고

숨은 로직 드러내기

async function fetchBalance() {
  const balance = await http.get<number>("...");
  logging.log("balance_fetched");
  return balance;
}
  • 이런 식으로 부수효과가 숨어있으면 안 됨 → 별도 함수로 빼고 호출 구조 명확히 드러내자

3. 응집도 – 관련된 건 함께 묶자

자주 같이 수정되는 파일은 같은 폴더에

  • Form.tsx, Form.styles.ts, Form.types.ts, Form.test.tsx는 같은 폴더에 있어야 자연스럽다

매직 넘버도 상수화해서 같은 맥락 안에 두기

  • 시간 상수, UI 딜레이 값 등은 의미 있는 네이밍과 함께 모듈화

한글 변수명도 상황에 따라 유효하다

  • 예: isGFSC → 국가지방자치단체_공공단체_금융사_여부
  • 도메인 맥락이 중요한 경우 오히려 한글이 더 명확하다 (토스 사례)

4. 결합도 – 책임은 나눌 수 있을 만큼 나누자

훅 하나에 너무 많은 걸 담지 말자

  • 이미지 업로드, 유효성 검사, 상태 관리, API 호출은 역할별로 나누자
  • 훅끼리 나누면 테스트도 쉬워지고 재사용성도 올라감

중복을 피하려다 더 망치는 추상화를 피하자

Props Drilling 해결할 땐 Context나 query param 활용

  • 깊게 props 전달할 때는 Context로
  • 페이지 간 상태 공유는 query param이 더 명확할 수도 있음

결론: 코드 품질은 작은 선택의 반복이다

코드 품질을 한 번에 확 높이긴 어렵지만,

  • 조건에 이름 붙이기
  • 상수 분리하기
  • 함수 분리해서 책임 명확히 하기

이런 사소해 보이는 선택들이 쌓여서 진짜 좋은 코드가 만들어진다.

그리고 그 판단의 기준은 결국, 내가 아닌 다른 사람이 이 코드를 보고 바로 이해할 수 있느냐다.

"좋은 코드는 결국 '덜 생각하게 만드는 코드다.'"

앞으로도 이 4가지 기준(가독성 / 예측 가능성 / 응집도 / 결합도)을 기준 삼아, 내 코드를 계속 점검하고 정리해나가고 싶다.