[7팀 황준태] Chapter3-1. UI 컴포넌트 모듈화와 디자인 시스템 - #32
Open
jthw1005 wants to merge 59 commits into
Open
Conversation
- 도메인 관련 코드 삭제
- Updated color tokens in color.css - Synced from figmaToken.json 🎨 Auto-generated by Figma Tokens workflow
🎨 Sync design tokens from Figma
- 색상 추가 및 롤백 - 하드 코딩 색상 수정
- Text, Alert, Modal, FormTextarea, Header 컴포넌트에 Tailwind 유틸리티 클래스 적용 - CSS 변수 구문 대신 표준 Tailwind 클래스 사용 (예: text-2xl, py-4, px-3) - 모든 render 함수 사용 스토리에 args 속성 추가하여 TypeScript 빌드 오류 수정 - 중복된 FormSelect.stories.tsx 파일 제거 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- native-select.stories.tsx를 NativeSelect 컴포넌트 전용으로 수정 - FormSelect.stories.tsx를 새로 생성하여 폼 컴포넌트 스토리 분리 - React import 누락 문제 수정 - 모든 스토리에 args 속성 추가하여 TypeScript 오류 해결 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chapter3-1. UI 컴포넌트 모듈화와 디자인 시스템
배포 링크
스토리북 링크
피그마 링크
과제 목표
레거시 코드베이스를 현대적인 디자인 시스템으로 개편하는 실무 경험
Before 패키지 분석 후 After 패키지 개편
개편 목표
디자인 시스템
컴포넌트 아키텍처
사용할 도구
TailwindCSS 4.x
shadcn/ui
CVA (Class Variance Authority)
React Hook Form + Zod
필수 과제
1. 디자인 시스템 구축
2. Before 패키지 분석
3. 컴포넌트 개편
심화 과제
추가 과제
과제 회고
이번 과제를 통해 얻어갈 수 있는 것들이 무엇일까 생각해보았다.
사내에서 기술 스택을 선택함에 있어서 자유롭기 때문에 아래 기술들은 회사에서 이미 많이 쓰고 있는 스택들이었다.
하지만, 회사에서 하는 프로젝트들은 전부 제로부터 시작한거라 큰 어려움이 없었고, 레거시 코드에서 시작해서 새로운 기술을 도입하는 것을 연습해 보기로 했다.
추가로 예전부터 조금씩 디자인 시스템에 관심이 있었어서 피그마에서 디자인 토큰을 깃헙 레포와 연동하고 이를 자동화하는 시스템을 만드는 것도 도전해 보았다.
1. 레거시에서부터 새로운 기술 도입하기
tailwindCSS와 shadcn을 활용해서 기존 컴포넌트들을 대체하려면 우선 어느정도 리팩토링을 하는 편이 좋겠다는 생각이 들었으나, 어디서부터 건드려야할지 굉장히 막막했다. 페이지 단위에서 시작하자니 비즈니스 로직이 혼재되어 있고 코드가 난잡해서 작은 UI 컴포넌트에서부터 아래 절차를 정하고 차근히 시작해보았다.
2번 과정이 제일 어려웠는데, 예컨대 FormInput 컴포넌트에서는 입력값의 타입에 따라서 validation 로직을 내부에서 들고 있어서, 이걸 그냥 지울 수도 없고 그렇다고 FormInput을 사용하고 있는 곳에서 일일이 검증 로직을 주입해주기도 난해해서 useFormValidation 훅을 만들어 검증 로직을 일단 분리했다. 추후에 해당 검증 로직들은 최종적으로 zod 스키마로 분리되었다.
또한, 이 과정에서 기존 디자인을 유지시키기 위해 코드를 수정하기 전 스토리북을 배포해놓고 수정 이후의 결과와 비교해보는 시도도 해보았다.
위와 같은 작업을 어느 정도 진행하다가, 어느 순간 페이지 단위에서 리팩토링을 하지 않으면 더 이상 나아가기 힘든 단계가 있었는데, formInput, formSelect가 그런 경우였다. 리팩토링하려 했으나 entity에 대한 로직 등 비즈니스 로직들이 산재해있어서 이것들을 먼저 걷어내야 했고, 근데 이것들을 걷어내려면 management 페이지 단에서 먼저 리팩토링이 되어야할거 같아서 entity를 기준으로 UserManagement와 PostManagement로 나눴다.
entity를 기준으로 여기저기서 분기 처리 되어있던 로직들이 사라지고 나니 이후에는 원활하게 작업이 진행되었다.
2. 피그마 디자인 토큰 연동 자동화
사실 이번 과제는 1번 보다는 2번에 더 초점이 맞춰져 있었다. 예전에 사내 디자인 시스템을 도입했다가 리소스 부족으로 인해 실패했던 경험도 있었고, 최근 팀이 성장함에 따라 내년 초에 디자인 시스템 구축 계획이 있기 때문이다.
따라서 과제를 하면서 자동화 과정을 먼저 연습해보기로 했다.
과제에서 사용하는 모든 디자인 토큰을 피그마에 만들어 놓으면 좋겠지만, 일일이 토큰을 등록하는 과정이 노가다이기도 하고 나는 디자이너도 아니니까 그냥 플로우를 구축하기위해 몇가지 컬러들만 피그마에 만들었다.
이후
Tokens Studio for Figma를 사용해서 깃허브 레포에 연동하고 figma-token 브랜치에 push해서 figmaToken.json 파일이 생성되는 것까지 확인했다.문제는 json 파일을 어떻게 tailwindCSS로 변화시키냐였는데, 스크립트 파일을 혼자 만들어보다가 시간을 너무 많이 잡아먹는 것 같아서 클로드 코드에 부탁하고 코드를 이해했다.
전체 흐름 및 핵심 로직들에 대한 요약
이후에는 figma-token 브랜치에서 push를 감지하면 생성된 figmaToken.json 파일로 스크립트 파일을 돌리고 결과물을 커밋 & 푸시한 다음 main 브랜치에 자동으로 PR이 생성되도록 구성했다.
이 때, 리뷰어 등록 및 Label 설정을 하려고 했으나 Github Bot이 이 동작을 계속해서 PR 업데이트로 처리해서 실패했다...
이제 디자이너가 디자인 토큰을 변경하고 이를 깃허브에 푸시하면 개발자가 확인 후 merge 하여 바로 서비스에 반영할 수 있는 자동화 흐름이 구축되었다.
추가로, 깃헙 레포로부터 pull을 땡겨오면 자동으로 피그마 디자인 토큰을 생성할 수도 있다. -> 이렇게 하면 아까 일일이 등록해주었던 디자인 토큰을 한 번에 등록할 수도 있다.
참고자료
깃헙 연동
push & pull
Before 패키지에서 발견한 문제점
사실 Before 패키지에 있는 코드는 일부러 안티 패턴으로 작성하신듯 보여서 문제점이 굉장히 많아 보였다.
관심사의 분리 X, DRY 원칙 X, 가독성을 떨어뜨리는 코드(ternary 연산자 등)도 많았다.
특히 그 중 두 개를 뽑는 다면, UI 컴포넌트 내부에 비즈니스 로직이 산재해 있는 것과 컴포넌트 설계가 아토믹 패턴으로 되어있는 것이다.
컴포넌트에서는 UI에 집중하고 비즈니스 로직은 커스텀 훅으로 분리하여 관심사를 분리시키는 것이 좋다. 둘이 같이 붙어있으면 UI 구조가 한 눈에 안 보이고 기획 수정에 따라 코드를 수정해야 할 때, 빠르게 수정하기가 어렵다. 어쩔 수 없이 도메인이 묻어야 하는 경우가 있는데 이 떄는 외부에서 주입시켜주는게 좋다고 생각한다.
아토믹 패턴은 일관적인 조각들을 활용하여 재활용성이 좋고 테스트도 용이하지만, 아토믹 패턴을 구축하기에는 리소스가 많이 들기 때문에 작은 웹 서비스에서 적용하기 과하다. 또한, 딱 정해주는 사람이 있지 않는 이상 특정 컴포넌트가 atom인지 molecule인지 구분하기도 애매하고 시간이 한참 지난 뒤에 다시 보면 얘가 왜 여기에 분류되어있지? 싶은 순간도 있었다. (-> 분명 내가 넣어놨다.)
개편 과정에서 집중한 부분
After 패키지에서, 위에서 언급한 두 가지를 집중적으로 개편하려고 했다. 디자인 시스템으로 추출할 수 있을 정도의 UI 컴포넌트에서(src/ui 경로)는 도메인과 분리되어 오직 UI 역할에만 집중하게 했고, StatusBadge, DashboardCard와 같이 어느 정도 도메인이 섞인 컴포넌트는 해당 도메인 feature 컴포넌트 내에 위치시켰다. 컴파운드 패턴으로 도메인을 주입받는 방식을 시도해보고 싶었지만, 시간이 부족해서 하지는 못했다.
아토믹 패턴으로 구성된 폴더 구조는 feature 단위의 폴더로 개편했다. User와 Post 두 개의 피쳐 단위가 명확하게 보였기 때문이다. 폴더 구조를 개편한 이후에는 entity를 기준으로 분기되어있던 코드가 깔끔해졌다.
어려웠던 점과 해결 방법
피그마 디자인 토큰을 json파일로 받아와서 tailwind 커스텀 클래스로 변환해주는 스크립트 파일 짜기
-> 혼자 해보려고 끙끙 대다가 AI의 도움을 받고 코드를 이해하려고 노력했다.
레거시 코드에서부터 시작하여 새로운 기술들을 도입해 나가는 과정
-> 작은 컴포넌트 단위에서 리팩토링하다가 어느 순간 페이지 등 큰 컴포넌트 단위에서 리팩토링을 해야하는 순간이 있는데, 그 특정 순간을 결정하기가 어려웠다.
리뷰받고 싶거나 질문하고 싶은 내용
오프 코치님 안녕하세요! 먼저 긴 글 읽어주셔서 감사드립니다! 🙇🏻♂️
아토믹 패턴을 도입하기 좋은 상황(또는 조건)이 뭔지 궁금합니다! 대규모 웹서비스거나 개발팀 규모가 클 때 효과적인 패턴인가요?
모노레포를 도입할 때, '이런 레포지토리끼리는 하나의 모노레포로 엮지 말아야한다.' 하는 레포지토리끼리의 상성 관계가 있을까요?
컴포넌트에서 비즈니스 로직을 분리할 때 어느 정도로 분리하는게 좋은지 판단이 서질 않습니다..! 예를 들어 컴포넌트에서는 이벤트 핸들러 정도만 남겨두고 나머지 로직은 최대한 커스텀 훅으로 분리하면 될까요? 아니면 컴포넌트에서 UI 구조가 명확히 잘 보인다 싶으면 비즈니스 로직 분리를 그만해도 되는 걸까요?
감사합니다!