Panda CSS로 디자인 시스템 만들기 (1) - 의사결정의 결정체

김유진·2024년 5월 2일
1
post-thumbnail

디자인 시스템?

GDSC Hongik 개발팀에 합류하게 되었다. 개발 팀은 GDSC Hongik이라는 커뮤니티를 운영하는 데 있어 발생하는 어려움을 기술적으로 해결하기 위해 존재하는 팀이다.

1년 전부터 스터디 관리에 본질적인 어려움을 겪고 있었기 때문에, 이를 타파하기 위하여 스터디 관리 통합 서비스를 개발하고자 하였고, 기존에 개발하였던 온보딩 서비스의 2차 MVP 개발을 진행하려고 하였다.

같은 커뮤니티에서 운영하는 서비스이기 때문에, GDSC Hongik에서 나오는 두 개의 서비스의 디자인 컨셉이 통일되면 좋겠다는 의견이 많았고, 이에 따라 디자이너와 협업하여 디자인 시스템을 제작하여 사용하면 좋겠다는 의견이 모아졌다.

또한, 2024-2에는 프론트엔드 React 스터디를 진행하려고 하였는데, 이 때 개발한 디자인 시스템을 활용하여 과제를 한다면 스터디를 수강하는 학생들이 디자인에 대해 신경쓰지 않고 개발 학습에 집중할 수 있을 것 같다는 생각이 들어 디자인 시스템의 필요성이 더욱 커졌다.

디자인 시스템은 의사결정의 결과물

디자인 시스템을 만들겠다고 결정을 한 이후, 한달의 시간이 지났다.
한달 동안 코드를 파파박 작성하여 몇 개의 컴포넌트에 대한 개발이 이미 끝나 있을것이라고 생각하였는데, 코드를 치는 시간보다 팀원들과 스터디와 회의를 진행한 시간이 더욱 많았다. 다소 지루할 수 있는 시간이라고 생각되는데, 디자인 시스템 제작에 대해 공감하고 함께 열심히 스터디를 진행한 팀원들에게 정말 감사한 마음이 들었다.

우리가 결정해야 할 내용들은 아래와 같이 정말 많았다.

  • 목표 : GDSC Hongik 서비스의 일관성 vs 사용자의 확장성
  • 학습 : 어떤 디자인 시스템의 오픈소스를 학습하고 대입할 것인지?
  • 정의 : 하나의 컴포넌트에 어떤 역할을 어떤 기준으로 부여할 것인지?
  • CSS : 컴포넌트의 CSS 구현 방식
  • 기타 등등 문서화 방법 / 테스트 / 디자인 시스템 패키지 배포 방법
  • 가장 중요한 디자인 시스템의 이름!

우리 팀이 고민했던 내용들을 이번 글로써 정리하고자 한다.

디자인 시스템의 목표

디자인 시스템을 만들고자 하는 동기는 글의 윗부분에 소개되었다. 우리의 디자인 시스템은 두 가지를 우선적으로 챙기고자 하였다.

  1. GDSC Hongik의 서비스의 디자인 일관성을 챙길 것
  2. 개발자가 빠르게 프로덕트를 만들 수 있는 기능을 제공할 것
  3. 추후 GDSC Hongik의 스터디에서 활용할 수 있도록, 개발을 처음 배우는 학생들이 쉽게 디자인 시스템을 사용할 수 있도록 할 것 (사용자 확보)

위의 목표를 달성하기 위하여 우리의 디자인 시스템은 확장성보다는 일관성을 챙겨 개발하기로 하였다. 디자이너와 디자인 시스템 레이어에 대한 부분을 엄밀하게 정의하고, 이를 명확하게 문서화하기로 하였다.

CSS 라이브러리 선택

"온보딩 서비스"의 2차 MVP 목표 중 하나는 Next.js 로의 마이그레이션이다. 그래서 우리가 만들고자 하는 디자인 시스템은 서버에서 CSS가 그려질 수 있어야 한다!

사실은 서버 사이드 랜더링을 고려하기 위해 디자인 라이브러리를 사용하지 않고, postcss만들 이용하여 디자인 시스템을 구현해야 한다는 고민을 굉장히 많이 하였다.
그러나, 디자인 시스템 제작에 주어진 기간동안 CSS만을 사용하게 된다면 시간 내에 모든 것을 끝내지 못할 것 같았고, 디자인 라이브러리와 친해지는 시간을 가지고 싶었던 욕심도 있었다.

그래서 서버에서의 CSS 주입시기를 함께 공부하며 적합한 라이브러리를 탐구하기로 하였다.
서버에서 CSS가 그려질 수 있는지가 가장 중요한 기준이었는데, 우리 팀이 고려해야 할 점들을 잘 정리한 자료를 찾게 되었다.

랜더링의 순서를 시각화한 자료이다.
Emotion과 Styled-component와 같은 런타임 styleSheet는 Critical CSS를 먼저 생성하고, 이후 Runtime시에 Js 번들과 함께 Style을 적용한다.

[이미지 출처]

최근 유행하고 있는 제로 런타임 라이브러리인 Vanilla Extract나 Panda css는 FP 가 일어나기 전 모든 CSS Style이 함께 로드된다.

그림으로 확인하면 FP시점이 런타임 stylesheet보다는 static한 CSS가 조금 더 느리게 넘겨받는다는 것을 알 수 있다.
이러한 제로 런타임 라이브러리가 런타임 오버헤드를 줄이는 것은 맞지만, 스타일 로드로 인하여 FP가 느릴 수 있다는 점은 감안하기로 했다.

결론적으로는 서버에서 잘 동작하는 Vanilla-extract와 Panda css 둘 중 하나의 라이브러리를 선택하게 되었는데, 아래 이유로 Panda CSS를 선택하게 되었다.

  1. 최근 가장 활발히 기여, 최신 업데이트가 일어나고 있음
  2. stitches, vanilla extract의 장점을 모아 개발한 라이브러리
  3. Zero Runtime 언어로써 런타임 오버헤드를 최소한으로 줄일 수 있습니다. = 빌드 타임에 CSS가 모두 생성됨
  4. Atomic CSS로 개발자가 편리하며 Type-safed한 언어임

다만, Panda CSS를 선택함으로써 우리가 감안해야 하는 주의사항도 정리할 수 있었다.

하나의 디자인을 구현하기 위한 여러 가지 방법이 열려 있어, 누가 작성해도 같은 결과물을 기대하기 어려울 수 있다.

왜 이렇게 구현에 있어 다양한 방법을 열어두었을까? 라고 생각해 보았는데, 아무대로 React 18의 서버 사이드 랜더링과 Next.js의 대두에 따라 서버사이드 랜더링을 중요시 하는 분위기가 유행하게 되었고, 현재 성공리에 운영되고 있는 디자인 시스템 서비스들도 제로 런타임 CSS 툴을 이용하는 쪽으로 마이그레이션을 해 나가고 있어, 이러한 마이그레이션에 적극적으로 대응할 수 있도록 열어둔 것 같다는 생각이 들었다.

모노레포 - Turborepo

디자인 시스템을 하나의 저장소에서 여러 개의 모노레포로 관리하는 방식을 채택했다. 이유는 다음과 같다.

  1. 디자인 시스템을 빠르게 테스트해볼 수 있다. (packages에서 제작한 코드 -> docs레포에서 바로 적용)
  2. 공통 패키지가 많은데, 이를 효율적으로 관리할 수 있다.
  3. 비슷한 일을 하는 코드를 같은 저장소에 두어 개발자가 관리하기 용이하다.

어떤 모노레포 툴을 사용할지에 대해서도 굉장히 많은 논의를 거쳤다. 많은 후보군들이 있었다. (lenra, yarn workspace, turborepo, nx 등등...) 우리 팀은 Turborepo를 선택하게 되었는데 아래 이유와 같다.

  • 초기 세팅의 간편함 (보일러플레이트 존재)
  • 캐싱을 통한 빌드 속도의 압도적인 속도

모노레포 말고도 신경써야 할 부분이 정말 많았기 때문에 초기 세팅이 간편하다는 장점이 가장 크게 와닿았던 것 같다.
다만, 레포지토리에서의 의존성 호이스팅이 불가능하여서 필요한 패키지는 각각의 레포에서 관리해주어야 한다.

pnpm을 쓰자!

기존에 팀원들 모두 yarn berry에 익숙해져 있었기 때문에 당연히 !! Turborepo + yarn berry로 세팅을 진행하고자 하였다.
그러나, Turborepo 공식 홈페이지에서 pnpm을 가장 1순위로 추천한 이유가 있었다고 한다....

[위 이슈의 원본 링크]

아쉽게도 아직 Turborepo에서는 yarn berry의 pnp 모드를 지원하지 않고, 앞으로도 지원하지 않을 예정이라고 한다. 공식 문서에서는 nodeLinker: node_modules로 변경하면 된다고 안내가 되어 있는데, node_modules를 사용할 것에 대한 아래와 같은 걱정이 앞섰다.

  • node_modules의 유령 의존성 여전히 존재하기 때문에 레포의 의존성 관리를 명쾌하게 하지 못한다.
  • 속도가 그닥 빠르지 않다. (성능 이슈)
  • yarn의 공식문서에서도 호이스팅 파일시스템이 완벽하게 대응이 안되어 있다는 단점을 언급하고 있다.

이러한 위험성을 굳이 감수하면서 yarn berry를 안고 가고 싶지 않았다. 그래서 떠오른 대안인 pnpm 을 고려하게 되었는데, 유명 디자인 시스템 라이브러리인 MUI도 최근 pnpm으로 패키지를 마이그레이션 한 것을 발견하여 이 결정에 자신감이 실리기도 했다. ㅎㅎ

그래서 결론은, pnpm을 선택하기로 했고, 우리의 주장은 아래와 같다.

  1. yarn, npm의 특성인 패키지 호이스팅을 통하여 중복 패키지 저장, 설치한적 없는 패키지 사용으로 인하여 잠재적인 버그를 발생하는 것을 예방할 수 있다.
  2. 속도에 있어 무지막지한 장점이 존재한다.

아직 pnpm이 국내에서 많이 사용되지 않아 래퍼런스가 적지만, 해외 래퍼런스와 공식문서를 최대한 참고해 보면서 공부해나가려고 한다!

배포 방식

트리쉐이킹

우리의 다자인 시스템에서 Dialog 컴포넌트만을 사용하였는데, 빌드한 웹 서비스에 Button에 대한 코드가 불필요하게 되어 있으면 안된다. 트리쉐이킹이 제대로 일어날 수 있도록, 이를 쉽게 도와주는 Rollup을 활용하고자 하였다.

패키지 배포

wowds/
├── apps/
│   └── wowds-docs/
└── packages/
    ├── wowds-ui/
		├── components/  
		├── hooks/
		└── utils/
    ├── wowds-icons/
    └── wowds-tokens/
​

모노레포 구조는 위와 같이 결정하였다. 우리가 배포할 것은 스토리북을 활용한 wow-docs (디자인 시스템 문서화), React에서 활용할 수 있는 컴포넌트를 정의한 wowds-ui, 아이콘,인 wowds-icons, 컬러 및 타이포 토큰값을 정의한 wowds-tokens 이다.

디자인 시스템 이름

위에서 디자인 시스템의 이름이 슬쩍 나왔는데.. 우리의 정체성인 GDSC Hongik이 모두 포함될 수 있는 이름을 2주나!! 고민했었다.

결론적으로 우리 학교의 상징이자 마스코트인

와우라는 이름을 따서, 와우디자인!!!으로 결정하게 되었고, 줄여서 wowds로 결론이 지어졌다!!!! (wow design system)

피카소 미안해...

어떤 패키지를 활용할것인지?

changeset

모노레포에서 서로 의존하고 있는 패키지의 버전을 확인하고, 이에 대한 일관성을 체크할 필요성이 있어 보여 changeset이라는 라이브러리를 활용하기로 했다.
ChangeSet을 선택하기로 한 이유는 다음과 같다.

  1. 변경 사항을 기록할 수 있음: 특정 패키지에 수정 사항이 발생하면 어떤 패키지가 수정되었는지 확인하여 .changeset 파일에 기록함
  2. 버저닝: 자동으로 패키지의 버전을 업데이트할 수 있음.
  3. 의존성 처리: 만약 수정된 패키지가 다른 패키지들에 의존성으로 포함되어 있을 경우, 이러한 의존성 관계를 고려하여 의존하는 패키지들의 버전도 적절히 업데이트함.

playwright

playwright는 아직 고민 중에 있다. 팀원들 모두 테스트에 대한 궁금증과 학습하고자 하는 열정이 활활 넘치지만, 아직 세팅 및 개발해야 할 것이 많았기 때문에 언급만 하고 아직은 도입한 단계는 아니다. 추후 세팅이 완료되고 가능하다는 결론이 나왔을 때 E2E 테스트도 병행하고자 한다.

Storybook

UI 테스팅 라이브러리 중 압도적으로 편리한 Storybook을 적극적으로 활용하기로 했다.
이는 wowds-uiwowds-docs 두 개의 패키지에서 각각 사용될 예정인데, wowds-uiDevdependences로 Storybook이 포함된 채로 배포가 되길래 맞는 것인지 꼼꼼히 확인해보고자 한다.

여기까지 GDSC Hongik 개발 팀의 디자인 시스템 탄생기와 의사결정에 대해 이야기하였다. 다음 글은 Rollup을 이용한 npm 배포 과정을 함께 둘러보고 배포한 디자인 시스템을 활용하여 웹 서비스를 배포 (빌드) 하였을 때, 배포한 번들러의 크기를 함께 살펴보고, 배포한 패키지의 롤업 세팅과 더불어, 트리쉐이킹이 올바르게 이루어지는지 정리한 과정을 작성하고자 한다. 😃

0개의 댓글

관련 채용 정보