I built a cross platform (React & React Native) design system at my last company. I'm in the middle of building another one for a client. Let me tell you what I learned, decisions I regret, and what I'm doing differently this time.
저는 이전 회사에서 크로스 플랫폼(React & React Native) 디자인 시스템을 구축했습니다. 나는 클라이언트를 위해 또 다른 것을 만드는 중입니다. 제가 배운 점, 후회하는 결정, 이번에는 다르게 행동하고 있는 점을 말씀드리겠습니다.
요약 :)
Agathist를 시작하기 전에 저는 헬스케어 스타트업의 "Frontend Platform" 팀에서 몇 년 동안 일했습니다. 내 임무는 회사의 모든 프런트엔드 클라이언트를 개발하는 데 사용할 도구와 내부 라이브러리를 구축하고 설계하는 것이었습니다.
내 모든 작업에는 하나의 고유한 제약이 포함되었습니다. 모든 것이 React 웹 과 React Native에서 모두 작동해야 한다는 것입니다.
이것은 많은 도전을 제시하고 이에 대해 많은 블로그 게시물을 작성할 수 있지만 오늘은 디자인 시스템에 대한 나의 가장 큰 실수라고 생각하는 것과 그렇게 생각하는 이유, 그리고 다르게 할 방법을 공유하고 싶습니다.
Agathist를 시작하기 전에 저는 헬스케어 스타트업의 "Frontend Platform" 팀에서 몇 년 동안 일했습니다. 내 임무는 회사의 모든 프런트엔드 클라이언트를 개발하는 데 사용할 도구와 내부 라이브러리를 구축하고 설계하는 것이었습니다.
내 모든 작업에는 하나의 고유한 제약이 포함되었습니다. 모든 것이 React 웹 과 React Native에서 모두 작동해야 한다는 것입니다.
이것은 많은 도전을 제시하고 이에 대해 많은 블로그 게시물을 작성할 수 있지만 오늘은 디자인 시스템에 대한 나의 가장 큰 실수라고 생각하는 것과 그렇게 생각하는 이유, 그리고 다르게 할 방법을 공유하고 싶습니다.
우리는 어떤 문제를 해결하고 있었나요?
디자인 시스템에 들어가기 전에 우리가 어떤 문제를 만들어서 해결하려고 했는지 논의하는 것이 중요하다고 생각합니다.
주요 문제는 다음과 같습니다.
불일치
그들의 제품은 시각적으로 일관되지 않았습니다. 제품 전반에 걸쳐 4가지 다른 시대의 스타일링을 쉽게 볼 수 있습니다. 시각적으로 매력적이지 않았습니다. 그들은 느낌과 사용자 경험을 통합하기 위해 앱 전체에서 사용할 수 있는 시스템을 원했습니다.
개발자 속도
개발자는 기능을 구축하고 출시하는 데 매우 느렸습니다. 이유 중 하나각주 전환 새로운 기능은 를 통해 맞춤형 CSS로 작성되었지만 styled-components그 중 어느 것도 유형이 안전하거나 체계화되지 않았다는 것입니다. 모든 것에 대해 수동으로 스타일을 작성하면 속도가 느려질 것입니다.
기존 '디자인 시스템'의 쓰레기통 화재
디자인 시스템에 대한 시도는 이미 존재했습니다. 작은 UI 라이브러리를 목표로 시작했지만 곧 모든 코드가 개발되는 곳이 되었습니다.각주 전환 이 모델에는 몇 가지 문제가 있었지만 가장 두드러진 점은 긴밀하게 결합되었습니다. 라이브러리에서 데이터 가져오기 호출이 있었고 모든 곳에 비즈니스 로직이 있었습니다. 더 이상 라이브러리가 아니라 기존 앱의 어색하고 흔적이 남아 있는 부속물이었습니다.
새로운 디자인 시스템으로 해결해야 할 문제가 더 많았지만 이것이 주요 문제였습니다.
내 솔루션
맞춤형 CSS가 전혀 필요하지 않고, 완전히 유형이 안전하며, 결코 긴밀하게 결합되지 않는 새로운 디자인 시스템을 만들어 이 세 가지 문제를 모두 해결할 수 있었습니다.
제가 선택한 방법은 Chakra UI 와 동일한 맥락에서 구성요소 세트를 개발하는 것이었습니다 . Chakra에 익숙하지 않다면 Chakra는 구성 가능한 구성 요소 세트이며 모두 Box. Box스타일에 매핑할 수 있는 많은 소품 세트가 있습니다. 여백, 패딩, 배경색 등에 관한 소품입니다.
나 역시 React Native Web 프로젝트를Box 기반으로 우리를 구축했지만 모든 소품은 우리 디자인 시스템에 맞게 만들었습니다. 예를 들어, 우리는 의 팔레트를 갖고 있고 색상 값을 에 전달하는 대신 색상 키를 작성 하고 내부적으로 매핑을 수행하도록 했습니다. 다음과 같습니다:colorsBox
I am some example text.
우리는 모든 소품을 키에 매핑하여 절대 벗어날 수 없도록 했습니다. 테두리 반경, 테두리 두께, 패딩 크기, 간격 크기 등 모든 것이 소품 시스템을 통해 수행되어야 했습니다. 뭔가 잘못했을 때 Intellisense 자동 완성 및 유형 오류가 발생했기 때문에 정말 멋졌습니다.
우리는 그 위에 다른 많은 구성 요소를 만들었습니다 Box. Rowand Stack및 Button, Input, 등과 같은 구성 요소 Textarea. 전체 시스템은 Boxes 및 Pressable및 와 같은 기타 기본 요소를 구성하는 데 구축되었습니다 Text. 그것은 견고한 기초였습니다. 견고했습니다. 부수거나 망칠 수는 없습니다. 사용 속도가 매우 빨랐으며 확장성이 매우 뛰어났습니다.
딱 하나의 문제가 있었습니다.
많은 사람들이 구성적으로 사물을 구축하는 데 어려움을 겪습니다.
이 회사는 실제로 백엔드 개발자인 풀스택 개발자를 역사적으로 과도하게 색인했기 때문에 프런트엔드 인재가 심각하게 부족했습니다. 이들 중 많은 사람들은 필요한 레이아웃을 얻기 위해 이러한 구성 요소를 적절하게 배열하고 구성하는 방법에 대해 머리를 감쌀 수 없었습니다. 그들은 정말 비극적인 CSS로 모든 것을 해결하는 데 너무 익숙해서 구성에 어려움을 겪었고 필요한 레이아웃을 달성하기 위한 대체 방법을 찾을 수 없었습니다.
설명하기 위해 지나치게 간단한 예를 들어 보겠습니다.
컴포지션을 사용하여 디자인하기
React와 React Native를 지원해야 하는 세상에서는 레이아웃 메커니즘이 하나뿐입니다: Flexbox. Flexbox는 본질적으로 구성 시스템입니다. 부모의 스타일은 자식의 스타일에 영향을 미칩니다. 구성은 어린이의 레이아웃을 변경하는 방법입니다.
width제가 처음 도착했을 때 디자이너들은 Button. 그들은 Button텍스트보다 조금 더 큰 s를 원했고, 우리는 그것을 버튼이라고 부를 수 있었고 , 부모의 전체 너비를 확장하는 s를 inline-block원했습니다 . Button그들은 두 가지 크기가 필요하다고 단호했습니다.
“아니요, 그렇지 않아요. 한 가지 사이즈만 있으면 돼요.” 나는 대담하게 말했다. 그들은 약간 충격을 받고 혼란스러워했습니다. 그리고 나는 그들에게 이것을 보여주었습니다.
다음은 두 Button가지입니다.
클릭 해주세요
클릭 해주세요
스타일적으로는 다른 점이 없습니다. 나는 그들의 마크업을 전혀 변경하지 않았으며 그들에게 다른 클래스를 부여하지도 않았습니다. 내가 한 일은 각각 Button의 Flex 컨텍스트를 변경한 것뿐입니다.
A는 StackFlex column컨텍스트, RowFlex row컨텍스트입니다. align-itemsFlex 컨텍스트의 기본값 은 입니다 stretch. 이는 Flex 부모의 자식이 레벨 요소 column와 유사하게 동작한다는 것을 의미합니다. block부모의 전체 너비를 채웁니다.
반면에 Flex 부모의 자식은 또는 요소 row처럼 동작합니다 . 최소 콘텐츠 너비의 크기로 축소됩니다.inlineinline-block
디자이너들은 렌더링된 컨텍스트를 변경하기만 하면 두 버튼을 모두 가질 수 있다는 사실에 약간 놀랐습니다 .
하지만 이는 개발자들에게는 어려운 일이었습니다. 그들은 -like 버튼을 갖는 방법이 inline-block그것을 Row. 여러 데모를 수행하고 문서에 예제를 작성한 후에도 마찬가지입니다 . 그들에게는 결코 직관적이지 않았습니다.
사람들은 "같은 너비의 버튼이 여러 개 나란히 있으면 어떻게 되나요?"라고 묻습니다.
쉬운. 더 많은 구성:
클릭 해주세요
클릭 해주세요
클릭 해주세요
모든 Flex 컨테이너에는 , , 또는 to .Item와 같은 값을 적용하는 데 사용할 수 있는 복합 구성 요소가 함께 제공됩니다 . 이를 통해 우리는 필요한 모든 준비를 구성할 수 있었습니다.growshrinkbasisalignSelf
한 단계 더 나아가 childrenFlex 컨테이너의 내부 를 Flex.Items로 래핑하고 다음과 같은 멋진 API를 제공할 수 있습니다.
이러한 구성 방식은 요소의 스타일을 지정하고 조작하는 다른 방법에도 적용됩니다. 예를 들어, box-shadowReact Native의 s는 정말 골치 아프기 때문에 Shadow내부적으로 모든 iOS 및 Android 마법을 수행하는 다른 구성 요소를 래핑하는 구성 요소를 만들었습니다.
{/* other stuff */}
전체 시스템은 우리가 원하는 것을 달성하기 위해 구성요소를 함께 구성하는 이러한 능력에 의존했습니다. 정말 탄탄한 시스템이었고 제가 자랑스러워했던 부분이었습니다.
그렇다면 문제는 무엇이었나요?
가장 큰 문제는 두 가지 유형의 구성이 있다는 것인데 , 대부분의 사람들은 객체 구성에는 괜찮지만 기능적 구성에는 그다지 좋지 않습니다.
이러한 종류의 구성에 대한 어려움을 겪으면서 저는 다음과 같은 사실을 깨달았습니다. 많은 개발자가 깊고 뿌리 깊은 지식에서 스타일을 작성하지 않으며 자신이 원하는 대로 작동하도록 작성해야 하는 내용을 정확히 알지 못합니다. 그들은 벽에 물건이 붙을 때까지 던져서 코드를 작성합니다.
약속해요. 그건 모욕이 아닙니다. 나는 실패한 사람이었습니다. 다른 개발자들은 아닙니다.
styled-components맞춤형 CSS를 반복해서 사용하는 것은 정말 느리고 문자 그대로 수천 줄의 불필요한 스타일링을 초래했지만 한 가지 큰 이점이 있었습니다. 사람들이 쉽게 시도해 볼 수 있다는 것입니다 .
예, 그들은 중복된 스타일을 많이 썼습니다. 예, 수많은 잘못된 선택이 있었습니다. 하지만 그들은 어느 정도 성공할 수 있었습니다. 사용자는 그것이 후드 아래에 뜨겁고 유지 관리할 수 없는 쓰레기 더미라는 것을 실제로 알지 못할 것이며 나중에 처리해야 할 다른 사람의 엉망이 될 것입니다.
차크라 UI와 유사한 시스템의 문제점은 전체 시스템에 탈출구가 거의 없다는 점이었습니다. 해결책을 찾는 방법을 실제로 이해해야 하거나, 아니면 막히게 됩니다. 누군가가 벽에 무언가를 던질 수 있을 만큼 표면적이 충분하지 않았습니다. 그것은 전적으로 의도된 것이었습니다. 이는 우리의 원래 문제를 해결했지만 많은 개발자가 .
내가 다르게 할 것
얼마 후, 나는 개발자들이 겪고 있는 어려움을 깨닫게 되었습니다. 아무리 많은 교육이나 문서도 도움이 되지 않는 것 같았습니다. 그들 중 일부는 그것을 이해하지 못했고 어쨌든 시스템을 배우려고 노력하지 않았습니다. 나는 그들에게 실패한 것 같은 느낌이 들었습니다.각주 전환
나는 내가 만든 새로운 문제에 대해 생각하는 데 많은 시간을 보냈고 결국 내가 다르게 할 것이 무엇인지 깨달았습니다. 만약 다시 돌아가서 할 수 있다면 / 대신 Tailwind/ 를 중심으로 디자인 시스템을 구축했을 것입니다 NativeWind.
내 주된 추론은 다음과 같습니다. 기능을 수행하는 것보다 개체나 토큰을 구성하는 데 어려움을 겪는 개발자가 적습니다. Chakra UI 스타일 디자인 시스템의 정확성을 보장하는 제한 사항 중 일부를 포기할 것이지만 개발자가 시험해 보는 것을 훨씬 더 쉽게 만들 것입니다. 또 벽에 물건을 던지려고요. 우리 코드베이스는 차선으로 작성된 기능을 더 많이 받게 되지만 최소한 기능은 갖게 됩니다.
내 생각에 이 경로는 맞춤형 CSS에서 클래스 styled-components작성으로 더 쉽게 도약할 수 있었을 것입니다 Tailwind.
이제 이 접근 방식에도 문제가 있습니다. 지난 몇 달 동안 저는 이 접근 방식을 따르는 클라이언트를 위해 또 다른 크로스 플랫폼 디자인 시스템(및 해당 앱)을 구축했습니다. Nativewind불완전하다,각주 전환 우리는 이 접근 방식을 사용하여 처음부터 많은 구성 요소를 구축해야 했지만 전반적으로 다른 개발자는 최소한 시도하고 앞으로 나아갈 수 있었습니다.
요약
어떤 사람들은 함수형 구성을 사용하여 필요한 것을 구축하는 데 항상 어려움을 겪을 것입니다. 탈출구가 더 필요해요. 시스템이 얼마나 제한적인지에 대해 올바른 균형을 맞추면 많은 개발자가 채택하기가 더 쉬워질 수 있습니다. 앞으로는 결정을 내릴 때 이 점을 더 깊이 고려하겠습니다.