# 최소 수준의 아키텍처 설정

## 아키텍처 설정

### 고민해봐야 할것

#### B2B vs B2C

* B2B와 B2C의 공통요소?
* B2B와 B2C의 디자인시스템 리소스 분리?
* 동일한 시스템은?&#x20;

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2F8MfzUfN4i97OR6zuatqo%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-19%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.55.13.png?alt=media&#x26;token=ab3793b3-4053-4860-a5e1-cd5a7a275191" alt=""><figcaption></figcaption></figure>

* B2B와 B2C간에 Space, Color 등 동일요소가 있을 수 있다.
* 두 데이터에서 공통으로 가져는 Foundation 영역
* 레이어 분리 필요&#x20;

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FKcZXzdvzm5tbgTTldY9m%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-19%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.59.26.png?alt=media&#x26;token=ae4cddb7-52af-47ac-8e5d-2a773e2988eb" alt=""><figcaption></figcaption></figure>

* 보통은 Library, Foundation으로 레이어 분리를 하고 디자인 시스템 내에 두 가지 계층으로 이루어진다.
  * 각각의 버전별로 운영
  * Library는 Foundation 기반으로 동작

{% hint style="info" %}
실무에서 필요한 부분을 먼저 고려하고, 공통의 아키텍처는 점진적으로 뽑아내도록 하자.
{% endhint %}

### Foundation

> 사전적 정의: 구조물의 견고한 기초
>
> -> 디자인시스템의 라이브러리를 이루는 견고한 기초 데이터들

* 파운데이션은 여러 개념이 포함됨
* 다만 모든 디자인시스템에 공통으로 들어가는 개념은 아님
* Color: 디자인시스템에서 사용되는 색상의 종류
* Spacing(Layout): 디자인시스템에서 사용되는 컴포넌트간 간격의 종류
* Typography: 글자를 표현하는 기준
* Icongraphy: 아이콘을 표현하는 기준
* etc...

{% hint style="info" %}
그냥 B2B, B2C 각각 디자인시스템을 두지 않고 왜 파운데이션을 정의해서 중앙화를 하는 것일까?
{% endhint %}

* 웹은 게임을 제외하면, 앱을 제작할 때 색상, 간격, 아이콘, 텍스트, 이미지 5가지로 대다수의 화면을 표현할 수 있다.

#### 파운데이션은 디자인시스템에서 제공하는 데이터의 구성모음이다.

* 파운데이션에 정의된 데이터를 바탕으로 컴포넌트는 개발된다.
* 컴포넌트를 개발하면서 파운데이션은 공통으로써 기능하므로 파운데이션 등록 프로세스를 견고히 운영해야 한다.
* **디자이너, 개발자 간 컴포넌트를 함께 정의**하며 커버리지를 최대한 파악한 후 파운데이션 버전은 최대한 보수적으로 운영해야 한다.
* 파운데이션과 컴포넌트의 버전은 따로 움직여야 한다.
  * **디자인시스템의 버전은 "컴포넌트" 버전**을 의미, 이 버전은 사용자 관점에서 보이는 것
  * 디자인시스템 실무자는 **"컴포넌트"와 "파운데이션" 두 가지 버전을 모두 이해하고 관리해야 한다.**

### 파운데이션을 사용하는 컴포넌트 구조도

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FdJ3bNvWX1thHQHJwmYit%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.22.54.png?alt=media&#x26;token=09a77b1f-da98-4799-85be-01ea42e1e8f4" alt=""><figcaption></figcaption></figure>

* 컴포넌트별로 버전이 필요한 이유는 컴포넌트별로 파운데이션이 바뀌었을때 사이드이펙트가 있을 수 있기 때문에 컴포넌트의 영향을 최소한으로 가기 위해 이러한 작업 진행

### 컴포넌트 개발을 위해 챙겨야하는 것

* 디자인시스템은 코드가 언제든지 사용자에게 보일 것을 염두해야 한다.
  * 코드가 복잡하고 이해가 되지 않으면 안된다.
  * 그렇기 때문에 모든 코드는 일관적이어야 하고 간단해야 한다.
* 컴포넌트의 개발 방법 통일
  * 코드 컨벤션
  * 코드 리뷰의 방법, 중요한 코드 SoC하기
  * 컴포넌트 로직, 레이아웃 분리

{% hint style="info" %}
Key Point: 정말 조그마한 것이라도 필수불가결한 공유는 필수!. 히스토리도 조그마한 것도 모두 기록해야 한다.

* 이유로, 디자인시스템의 모든 논의과정은 사용자가 알 수 있어야 한다.
* 디자인시스템은 "공통 조직"이기 때문에 중립적이어야 한다.
  {% endhint %}

### 디자인 언어 (Design Language)

> 용어의 통일: 가장 중요한 디자인시스템에서의 개념
>
> 디자인시스템은 용어 통일을 단계적으로 진행해야 한다.

* 첫 번째 용어 통일 대상자: 디장니시스템을 개발하는 개발자와 디자이너
  * 서로의 툴(소프트웨어, 피그마, ...)에서 사용되는 용어를 통일
  * 가급적이면 디자인에 통일 시키되, 개발에만 필요한 부분은 따로 용어로 정리한다.&#x20;
  * 디자인의 경우 디자인에 특화된 언어라기 보다는 비즈니스 특화된 언어를 고를 가능성이 크다.
* 두 번째 용어 통일 대상자: 디자인시스템을 사용하는 개발자와 디자이너 그리고 PM/PO
  * **사용자 입장에서 디자인 언어를 통해 서로간 동일한 명칭을 사용**하므로써 "**커뮤니케이션 비용을 절감**" 한다.
  * <mark style="color:red;">**커뮤니케이션 비용을 절감하는 것은 디자인 언어, 나아가 디자인시스템의 가장 중요한 역할**</mark>

### 디자인 언어의 역할

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FNWZs3Wj5q7uRo4RKthrj%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.35.25.png?alt=media&#x26;token=a250670c-21a5-465d-be45-ec1914daa8e7" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2F2gu8FE70cWPVOslAsWq4%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.36.13.png?alt=media&#x26;token=755fe7a0-6096-44a8-b44c-9c47c889f4e0" alt=""><figcaption></figcaption></figure>

1. 디자인시스템 개발자(디자이너/개발자)간의 커뮤니케이션에 필요한 언어
2. 디자인시스템 개발자와 사용하는 사람 간의 커뮤니케이션에 필요한 언어

#### e.g)네이버의 버튼 컴포넌트 예시

* 구성요소: Border, Typography, Icongraphy
* 컴포넌트는 확장가능 해야 한다.
  * 현재) 로그아웃 우측에 Exit Icon이 있음
  * 미래) 로그아웃 좌측에 Exit Icon을 배치할 수도 있다.
  * 그마저도 모바일과 PC는 다를 수 있다.
* 디자인시스템 개발자들이 항상 하는 생각: 비즈니스가 우리의 상상보다 더 많은걸 필요로하면 어떻게 해야하는가?

  * Button 컴포넌트는 Left, Right, Middle 등의 레이아웃 구조와 관련된 영역이 존재
  * 사용처에서는 "Left", "Right", "Middle" 등의 개념을 이해하지 않아도 되게끔
  * 컴파운트 컴포넌트 패턴 등을 이용해 제공하거나, 인터페이스 주석을 달아 제공
  * 버튼 컴포넌트 내부적으로 여러 레이아웃에 대한 자동화, 코드등은 사용처에서 모르도록 각자의 언어를 만드는 것이 필요

{% hint style="warning" %}
버튼 컴포넌트 내부적으로 Left, Right, Middle이 있어요라고하면 디자이너들이 알아듣기 쉽지 않기 때문에 공식적으로 이런 기능들, 컴포넌트를 유연하게 제공하기 위해 이런 용어들을 정식적으로 채택할것인지 아닌지 고민해봐야 한다.
{% endhint %}

* 버튼의 예시처럼 디자인시스템은 컴포넌트가 점점 많아지고, 잘게 쪼개진다.
* 그러면서 같은 컴포넌트 하나에 레이어가 수십개 존재하게 될 수도 있다.
  * e.g) 네이버의 버튼에 좌,우만 있는게 아닌 상,하가 생길수도 있고, 애니메이션 등이 외부에 생길 수도 있다.
* 그렇기 때문에 디자인시스템 개발하는 곳에서 쓰이는 언어와 사용하는 측에서의 언어를 분리해서 제공해야 한다.
  * 이러한 역할을 하는 것이 디자인 언어이며, 디자인 언어는 각 사용되는 영역에서 저마다 구축해야 한다.

### 자동화된 디자인시스템 개발 및 운영 프로세스

#### 디자인시스템을 성공시키기 위해 가장 중요한 개념

* 디자인시스템은 만들지 않는 것이 제일 성공확률이 높다.
  * 제작을 위해 들어가는 팀, 개발 리소스, R\&R 분리 등 정말 많은 고려필요
* 디자인시스템을 구축하게되면 두 가지를 항상 고민해야 한다.
  * **첫 번쨰: 디자인시스템을 어떻게 전파하고 실제로 사용 시킬 것인가?**
  * **두 번쨰: 사용자에게 신뢰성이 있는 컴포넌트를 어떻게 개발하고 운영할 것인가?**

#### **첫 번쨰: 디자인시스템을 어떻게 전파하고 실제로 사용할것인가**

* 디자인시스템은 사용을 위해 적극적인 어프로치와 완성도 높은 퀄리티의 결과물이 필요
  * 상위 조직 및 유관 부서 설득을 통해 적용 일정을 잡는 것이 첫 목표
  * 무엇이든 적극적인 어프로치 그리고 사용처를 확보하지 못하면 아무리 좋아도 의미가 없다.
  * 적용을 통해 완성도가 높다는 걸 입증하고 결과 단계에서 어떠한 성과 (기간 단축)이 있는지 체크를 통해 발표 등 노력
* 조직 관점에서 고민
  * 디자인시스템을 사용하는 부서를 어느정도 인원이 얼만큼 서포트하는데 리소스를 쓰는가?
  * 운영 리소스와 신규 피처 개발, 버그 픽스 등 리소스는 잘 배분되어 사용되어 있는가
  * 신규 디자인시스템을 적용하는 과정을 기본적인 리소스에 3\~4배는 사용된다고 생각해야함
    * 개발자가 알지못하는 버그와 수많은 질의응답의 시간이 기다리기 때문

#### 두 번째: 사용자에게 신뢰성 있는 컴포넌트를 어떻게 개발하고 운영할 것인가

* 디자인시스템 전파에 어느정도 성공해서 여러 부서가 사용할 때
  * 컴포넌트 변경사항이 적도록 고민 필요
  * 장애를 내지 않도록 다양한 OS 단위의 테스트 필요
  * 수많은 CS 등을 처리할 수 있는 자동화된 운영 프로세스 구축 필요

### 업무 프로세스 구축하기

* (개발 방법 구축) 배포 / 브랜치 (소스코드) 운영 방식
* (개발 환경 구축) 피쳐 / 수정단위의 변경사항 확인을 위한 테스팅 환경 구축
* (커뮤니케이션 자동화) 사용자와 커뮤니케이션을 위한 채널 정리 및 업무 상황 확인

#### 개발 방법 구축) 배포 / 브랜치 (소스코드) 운영 방식

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FpDUy5zfpQcAAmh74kYUR%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.55.21.png?alt=media&#x26;token=e1fbe5c8-fbbb-48c2-af52-a37e9cfc5aac" alt=""><figcaption></figcaption></figure>

* **추천) Trunk-Based Development**
* 단일 브랜치에서 모든 작업을 진행, 소규모 단위의 배포를 잦게 일어나도록 한다.
* 대다수의 디자인시스템 컴포넌트는 컴포넌트 별 버전이 존재하고, 코드 전역적으로 브레이킹 체인지가 일어나지 않기 때문에 베타/릴리즈 등 수많은 브랜치의 존재가 필요없음
* 그 과정에서 수많은 테스트와 엄격한 규칙이 동작해야 Trunk-Based Development는 지켜질 수 있다.
  * 디자인시스템의 경우 컴포넌트 별 테스트를 중요하게 지켜야 하므로, 엄격한 규칙을 지키기에 최적화된 프로덕트

#### 개발 환경 구축) 피처 / 수정 단위의 변경사항 확인을 위한 테스팅 환경 구축

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FTE6ikrtO2KSL8cPjp0wr%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.56.37.png?alt=media&#x26;token=39745d15-fd13-496b-a171-2bf1f5bed569" alt=""><figcaption></figcaption></figure>

#### 커뮤니케이션 자동화) 사용자와의 커뮤니케이션을 위한 채널 정리 및 업무 상황확인

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FyfjdSLSEhObFX2cUQTy9%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-03-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.57.57.png?alt=media&#x26;token=18464f82-59d4-42b3-a272-23121b27e74a" alt=""><figcaption></figcaption></figure>

### 테스트: 디자인시스템의 필수적이고 핵심적인 수단

* 디자인시스템은 테스트가 되지 않으면 사용되는 영향 범위가 넓을수록 문제가 커지게 된다.
  * 사용하는 팀이 100개라하면 하나의 문제가 100개의 팀에 영향을 주기 때문
* 세 가지 주요로 봐야할 디자인시스템의 **핵심 테스트**
  * **첫 번째: 정상적으로 동작하는가?**
  * **두 번째: 레이아웃이 문제 없이 동작하는가?**
  * **세 번쨰: 모든 환경에서 동작하는가?**

{% hint style="info" %}
세 가지 측면에서 어떤 테스트 방법을 사용하면 좋을지 체크해보자.
{% endhint %}

#### 첫 번쨰: 정상적으로 동작하는가

* 기본: 컴포넌트 단위로 버전을 제공, 컴포넌트 버전 레벨로 버그를 격리
  * 예를들어 문제 로직을 버튼과 리스트에서 사용한다 할 때, 버튼만 버전을 올리면 버튼에만 영향이 있을 것
  * 이는 정상적으로 동작할 수 있도록 영향 범위를 제어하는 역할을 함
* 코드리뷰: 정상적으로 동작하는지 개발자 레벨에서의 코드리뷰 활동에서 체크할수 있도록 한다.
  * 피처 단위의 테스트 환경 구축을 통해 이를 가능케 한다.
* 테스트 코드: 컴포넌트 테스트, 통합 테스트, 단위 테스트를 핵심적으로 이용
  * 기본적으로 디자인시스템은 브라우저 이벤트를 제외한 비동기 동작은 잘 활용하지 않을 것
  * 기능들에 대해 단위/통합 테스트를 Jest나 Vitest 등을 통해 로직 작성
  * 컴포넌트 테스트는 E2E 툴을 이용해 진행 (더불어 접근성 테스트도 진행)
  * <mark style="color:red;">**중요) 레이아웃 테스트는 이 단계에서 진행하지 않는다. 로직에 대한 검증만**</mark>
*

#### 두 번째: 레이아웃이 문제없이 동작하는가?

* 레이아웃과 로직 테스트를 분리한 이유는 로직 (HTML/CSS)로 하여금 100% 브라우저의 레이아웃이 동일할것으로 체크하지 못하기 때문
  * 이 세상엔 다양한 브라우저, OS가 존재하고 그들마다 처리하는 방법이 다르기 때문
* 여러 레이아웃에서 다른 문제를 검증하기 위해 pixel 단위로 체크하는 "**시각적 회귀 테스트**"를 이용한다.
  * **`스토리북과`** **`퍼펫티어`**&#xB97C; 이용해서 공통 서버를 올린다음, 공통 서버 내에서 여러 브라우저를 테스트할 수 있는 환경을 구축한다.
  * 각 개발자 별 브라우저에서 테스트보다, 공통의 테스트 슈트를 검증할 수 있는 공통 서버를 구축하는것이 중요하다.
    * 초기에는 큰 성능을 요하지 않으므로 서버 한 대에 도커 여러개를 물려서 브라우저 환경 테스트를 진행해도 좋다.
* 시각적 회귀 테스트는 배포 전 무조건 이루어져야 하며, 문제 있을 시 배포가 이뤄지지 않도록 제공한다.
  * **`browserlist`** 등으로 제공 버전등을 명확하게 하자

#### 세 번쨰: 모든 환경에서 동작하는가?

* 레이아웃과 이어지는 내용
* OS/Browser 별로 달라지는 환경에 대해 테스트 구비 필요
* 필요하다면 사내 QA 팀과 함께 테스트할 수 있는 방안 마련 필요
  * 디자인시스템을 구축할 수준의 회사라면 QA 팀이 존재할 것으로 기대
  * 그렇지 않다면 디자인시스템을 구축하는 의미가 퇴색된다.
    * 비즈니스를 치기도 바쁜 환경에서 디자인시스템은 비즈니스를 더 오래 배포가 못나가도록 한다..
