스프린트에서 컴포넌트 먼저 만드는 이유

HANUI·
애자일프론트엔드디자인시스템스프린트컴포넌트

스프린트 백로그는 보통 이렇게 쪼개져요.

화면 단위예요. 기획도 화면 단위고, QA도 화면 단위고, 데모도 화면 단위니까 자연스러워요.

그런데 이 순서대로 개발하면 3번째 스프린트쯤에 이상한 일이 생겨요.

이전 편에서 "UI 개발자는 디자인을 기다릴 필요 없다"고 했는데, 이번 편은 그다음 문제예요. 디자인을 안 기다린다고 쳐도, 뭐부터 만들 것인가.

화면 단위로 만들면 생기는 일

Sprint 3쯤 코드베이스를 열어보면 이래요.

버튼이 5개예요. 다섯 명이 만든 것도 아니고, 한 사람이 3주에 걸쳐 만든 거예요.

테이블도 마찬가지예요. 게시판 목록 테이블, 사용자 관리 테이블, 첨부파일 테이블 — 정렬 로직이 세 군데에 각각 있어요. 그중 하나만 접근성 처리가 돼 있고요.

문제는 이게 버그가 아니라는 점이에요. 다 동작해요. 데모도 통과했고, QA도 통과했어요. 그래서 아무도 이걸 티켓으로 만들지 않아요.

그러다 Sprint 5에서 디자이너가 "버튼 호버 색상을 조금 진하게 바꿔주세요"라고 해요. 5분이면 될 일인데 5군데를 고쳐야 하고, 그중 하나를 빠뜨려요. 그 하나는 3주 뒤 사용자가 발견해요.

화면 단위 스프린트의 비용은 스프린트 안에서 안 드러나요. 다음 스프린트에 청구돼요.

그래서 컴포넌트 먼저

컴포넌트 우선(component-first)은 거창한 게 아니에요.

화면을 만들기 전에, 그 화면들에 뭐가 들어가는지 목록을 먼저 뽑는 것이에요.

스프린트 시작 전에 와이어프레임 전체를 한 번 훑어요. 이번 스프린트 화면만이 아니라 가능하면 전체 화면을요. 그리고 반복되는 요소를 적어요.

요소등장 화면판단
버튼전부Component
입력 필드로그인, 작성, 검색Component
테이블게시판, 사용자, 파일Component
페이지네이션게시판, 사용자Component
검색바(입력+버튼+필터)게시판, 사용자Block
로그인 폼로그인Block
게시판 CRUD 일체게시판 3화면Kit
대시보드 차트대시보드나중에 (1곳)

이게 컴포넌트 인벤토리예요. 반나절이면 나와요.

와이어프레임이 있으면 이미 답이 다 나와 있어요. "여기 테이블"이라고 적힌 곳이 세 군데면, 테이블 컴포넌트는 확정이에요. 추측이 아니라 문서에서 읽어낸 사실이에요.

3층으로 나누면 판단이 쉬워져요

HANUI에서는 이걸 세 단계로 나눠서 관리해요.

Component — UI의 원자 단위. 상태 없음. 어디서든 재사용.

Block — Component를 조합한 완성된 패턴. 로컬 상태만 가짐.

Kit — 특정 도메인의 완전한 기능 집합. API, 상태, 훅까지 포함.

// API 주소만 바꾸면 게시판 하나가 통째로 붙어요
<BoardList apiBaseUrl="/api/notices" />

이렇게 나눠두면 "이건 어느 층에 만들지" 하나만 판단하면 돼요.

  • 상태가 없고 혼자 쓰이면 → Component
  • 여러 Component를 묶고 로컬 상태가 있으면 → Block
  • API랑 전역 상태가 붙으면 → Kit

스프린트 티켓도 이 단위로 쪼개요. "게시판 목록 화면" 하나짜리 티켓보다 "DataTable 컴포넌트 / SearchBar 블록 / 게시판 목록 조립" 세 개가 리뷰하기도, 나눠 맡기도 쉬워요.

그럼 첫 스프린트가 느려지지 않나요?

솔직히 느려져요. 첫 스프린트에 데모할 게 적어요.

이게 컴포넌트 우선의 진짜 어려운 점이에요. 기술적으로 어려운 게 아니라, 첫 스프린트 리뷰에서 보여줄 화면이 없다는 걸 설득해야 하는 게 어려워요.

두 가지로 접근해요.

1. 스프린트 0을 따로 두기

일정에 여유가 있으면 35일짜리 스프린트 0을 잡아요. 컴포넌트 인벤토리 뽑고, 토큰 세팅하고, 자주 쓰는 컴포넌트 1015개를 만들어요. 데모는 화면이 아니라 컴포넌트 카탈로그로 해요. Storybook이든 데모 페이지든요.

이게 의외로 이해관계자한테 잘 먹혀요. "이 조각들로 앞으로 모든 화면을 만듭니다"가 눈에 보이니까요.

2. 스프린트 안에서 앞단 하루

스프린트 0을 못 잡는 상황이 더 많아요. 그러면 매 스프린트 첫날을 컴포넌트 데이로 써요. 이번 스프린트 화면 3개에서 공통 요소를 뽑아서 그것만 먼저 만들고, 남은 4일에 화면을 조립해요.

완벽하진 않아요. Sprint 1에서 만든 버튼을 Sprint 2에서 조금 고치게 돼요. 근데 고치는 것과 새로 만드는 건 완전히 다른 비용이에요.

과설계는 어떻게 피하나

컴포넌트 우선의 반대편 함정이 이거예요. 아무도 안 쓸 컴포넌트를 만드는 거요.

규칙 두 개면 충분해요.

규칙 1: 와이어프레임에 두 번 나오면 만든다. 한 번이면 화면 안에 둔다.

대시보드에만 있는 차트는 컴포넌트로 안 빼요. 그냥 대시보드 폴더에 둬요. 나중에 두 번째 화면에서 필요해지면 그때 승격시켜요. 파일 옮기는 데 5분이면 돼요.

규칙 2: 지금 필요한 props만 만든다.

variant를 6개 만들어놓으면 그중 4개는 안 쓰이고, 안 쓰이는 4개도 디자인 변경 때마다 같이 고쳐야 해요.

컴포넌트 우선은 "미리 많이 만드는 것"이 아니라 "겹치는 걸 한 번만 만드는 것"이에요. 이걸 헷갈리면 그냥 과설계가 돼요.

팀 전체에는 이렇게 작용해요

컴포넌트가 먼저 나오면 이전 편에서 얘기한 병렬 작업이 한 겹 더 깊어져요.

화면 하나당 UI 작업이 3일에서 1일로 줄어요. 조립만 하면 되니까요. 그만큼 로직 개발자가 기다리는 시간도 줄어요.

부수 효과도 있어요.

  • PR이 작아져요. "화면 하나 통째로 300줄"이 아니라 "Button 컴포넌트 60줄"이라 리뷰가 실제로 이뤄져요.
  • 접근성을 한 번만 해결해요. 키보드 네비게이션, aria 속성, 포커스 관리를 컴포넌트 안에서 끝내면 그걸 쓰는 모든 화면이 자동으로 통과해요. 화면마다 따로 하면 빠뜨리는 곳이 반드시 생겨요.
  • QA가 층을 나눠서 볼 수 있어요. 컴포넌트 레벨 검증이 끝나 있으면 화면 QA는 "데이터가 맞게 들어갔나"만 보면 돼요.

정리

  1. 화면 단위 스프린트의 비용은 다음 스프린트에 청구된다 — 버튼 5개, 테이블 3개는 버그가 아니라서 아무도 티켓을 안 만든다
  2. 와이어프레임에서 인벤토리를 먼저 뽑는다 — 추측이 아니라 문서에서 읽어낸 사실이라 반나절이면 나온다
  3. Component / Block / Kit 3층으로 나누면 판단이 단순해진다 — 상태와 의존성이 기준
  4. 두 번 나오면 만들고, 지금 필요한 props만 만든다 — 이 두 규칙이 과설계를 막는다

컴포넌트 우선은 결국 "두 번 만들지 않기" 예요. 애자일이 빠른 이유는 빨리 짜서가 아니라 다시 안 짜서니까요.


관련 링크

시리즈: 애자일과 프론트엔드

HANUI

KRDS 기반 React 컴포넌트 라이브러리. 공공 웹 개발을 더 쉽게.