Atomic Design을 응용해 React 프로젝트 구조를 설계하고 기술 스택을 결정한 경험

moai·2020년 12월 24일
11
post-thumbnail
post-custom-banner

부스트캠프 프로젝트에서 Atomic Design을 응용해 프론트엔드 프로젝트 구조를 설계하고 기술 스택을 결정한 경험을 공유할까 합니다.
우측 링크에서 프로젝트 소스코드를 확인해 보실 수 있습니다. 👉 GitHub 링크

Atomic Design이란?

아토믹 디자인

Atomic Design은 원자가 결합해 분자가 되고, 분자가 결합하여 유기체가 되는 것처럼, UI 컴포넌트를 가장 작은 단위로 쪼개고 합치며 UI를 마치 레고 블럭 쌓듯이 만들어나가는 방법입니다.

일반적인 Atomic Design에서는 아래와 같은 단계로 컴포넌트를 관리합니다.

Atoms: 하나의 구성 요소. 본인 자체의 스타일만 가지고 있으며 다른 곳에 영향을 미치는 스타일은 적용되지 않아야 함.
Molecules: 원자들의 모음
Organisms: 분자들의 모음
Templates: 유기체들을 모아 템플릿으로 생성
Pages: 실제 페이지를 구성

왜 Atomic Design을 사용했을까?

저희는 기획 단계에서 컴포넌트를 재사용 가능하게 만들자! 라는 목표를 가지고 Atomic Design을 프로젝트에 적용하고자 했습니다.

왜냐하면 대부분의 프로젝트에서 Button, Input 등의 요소의 디자인은 거의 바뀌지 않고 재활용 되어서 쓰이는 경우가 많기 때문입니다. 우리 프로젝트에서도 Button, Input 등의 요소는 계속 반복되어 사용되었고, 이를 재사용 가능하게 만들고자 하였습니다.
아래 두개의 사진은 우리 프로젝트를 디자인 할 때 사용된 디자인 툴인 피그마를 캡쳐한 사진입니다. 버튼이 계속 반복되어 사용되는 것을 확인할 수 있습니다.


우리가 느낀 Atomic Design의 장점

첫째로, 예측했던 것처럼 컴포넌트 재사용이 매우 편리했습니다. Button, Input을 한번 만들어 놓으면 다시 만들 필요가 없고 가져다 사용하기만 하면 되서 개발 속도가 빨랐습니다.

또한, Atomic Design을 사용해 개발하면, 컴포넌트 단위의 분업이 가능하여 협업하기에 무척 편리했습니다.
우리 팀은 다 같이 컴포넌트를 쪼개고, 각자 맡은 부분의 Atom을 만들었습니다. 이렇게 개발하니 서로가 독립된 환경에서 작업할 수 있어 개발 속도가 빨랐습니다.

Atomic Design의 장점을 극대화 하기 위해

우리는 컴포넌트 단위의 분업의 장점을 극대화 하기 위해 StoryBookStyled Components를 사용하기로 결정했습니다. 각각을 사용한 이유는 아래와 같습니다.

StoryBook


최소 단위의 컴포넌트를 페이지에 부착하지 않고도 제작과 동시에 바로 테스트하기 위해 사용했습니다. props의 따라서 변화하는 경우도 디자인을 비교할 수 있어 개발 속도를 향상시키고, 동료의 작업 내용을 바로 확인할 수 있어 내가 만들지 않은 컴포넌트도 바로 확인할 수 있었습니다.

Styled Components


CSS가 컴포넌트 단위로 구성되기 때문에 CSS간 의존성이 없고, 클래스로 구분하는 작업이 불필요하고 컴포넌트의 독립성이 보장되어 개발 속도를 높히기 위해 사용했습니다.

우리가 느낀 기존 Atomic Design의 단점

우리는 Atomic Design은 좋은 점도 있지만, 그에 못지 않은 단점이 있다고 판단했습니다.
우리가 판단한 단점은 아래와 같습니다.

1. Props Drilling
기존 Atomic Design에서는 재사용 가능한 컴포넌트를 만들기 위해, 아래 그림과 같이 Pages 단계에서 상태와 로직을 정의하고, 상태나 로직을 Template, Organism, Molecule, Atoms에 Props로 쭉 내려주어야 합니다.
혐짤
이렇게 Props를 내려 꽂았을 때 만약에 Page에서 Template으로 내려줘야 할 State의 자료형이 바뀐다면,
Template의 매개 변수를 바꿔줘야 하고, 이에 따라 Organism의 매개 변수도 바꿔줘야 하고, Molecule의 매개 변수를 바꿔줘야 하고, Atom의 매개 변수를 바꿔줘야 합니다.
State의 자료형이 바뀌었을 때, 상당히 많은 부분의 코드가 바뀌어야 한다는 점이 우리에게 단점으로 다가왔습니다.

2. 과연 Template를 재활용 할까?
Template은 상태, 로직이 존재 하지 않는 하나의 Page입니다.
우리는 Page UI가 통채로 재활용 될 일은 없다고 판단했습니다.
이러한 상황에서 우리 프로젝트에서 Template이 존재하는 것은 Atomic Design의 구색을 맞추기 위해 억지로 사용하는 것 같다는 생각이 들었습니다.

그래서 어떻게 단점을 해결했나요?

우리는 과도한 Props DrillingTemplate 재활용 불가능 이라는 단점을 해결하기 위해,
어차피 재활용 되지 않을 Template을 버리고 State, LogicOrganism 단계에 심어서 Props Drilling을 줄였습니다. 그리고 PageOrganism을 배치하는 용도로 사용하였습니다.

이렇게 프로젝트 구조를 가져가게 된다면, Atom, Molecule을 상태에 종속되지 않게 만들어 재활용 할 수 있게 되어 Atomic Design의 장점을 살리고, Props Drilling을 최소화해서 Atomic Design의 단점을 줄일 수 있었습니다.

Organism에 상태를 심으니 발생한 문제

상태들이 각각의 Organism에 존재하니 다른 Organism에서 선언된 상태를 사용할 수 없다는 문제가 있었습니다. 우리는 이 문제를 해결하기 위해 상태 관리 라이브러리를 사용하기로 했습니다. 상태 관리 라이브러리를 사용하면 상태를 여러곳에서 사용할 수 있어 우리의 문제를 해결할 수 있었습니다.

어떤 상태관리 라이브러리를 사용할까?

상태 관리 라이브러리를 사용하기로 마음먹은 뒤에는 어떤 라이브러리를 사용할지에 대한 고민이 시작되었습니다.
우리는 Redux, Context API, Recoil 총 3개의 라이브러리를 후보에 올리고, 각각의 라이브러리에 대해 학습한 뒤 회의를 거쳐 라이브러리를 선정하였습니다.

우리는 결론적으로 아래와 같은 이유로 Redux를 쓰기로 결정했습니다.

Context API는 React 전역 상태 관리를 위해 제공하는 기본적인 방법이지만, 기능별로 Context를 만들어야 한다는 수고로움과 Context의 상태가 바뀔때, 해당 Context의 Provider 내부 컴포넌트가 전부 리렌더링 되는 문제, 비동기 처리를 관리하기 까다롭다는 단점이 있어 사용하지 않기로 하였습니다.

Recoil은 Facebook이 만든 상태 관리 라이브러리 입니다. 단순하고 사용하기 편리했지만, 2020년 12월 12일 기준 0.1.2 버전으로, 아직 안정화가 되지 않은 상태이고, 레퍼런스가 부족하기 때문에 사용하지 않기로 하였습니다.

Redux는 비동기 처리를 위한 미들웨어(Redux-thunk)가 편리하고, 글로벌 상태를 하나의 객체안에 넣어서 사용하기에 Context API를 사용할 때 처럼 여러 Context를 선언할 필요가 없어서 사용하기 편리하기에 사용을 결정하였습니다.

프로젝트 구조

내용을 종합하여 최종 프로젝트 구조를 아래와 같이 결정했습니다.

┌── node_modules
├── src
│   ├── @types                  		
│   ├── assets                  	
│   ├── components                   
│   │   └── atoms     		   		
│   │   └── molecules      
│   │   └── organisms       
│   ├── stories  
│   ├── modules  
│   │   ├── index.ts   - 리듀서 합치는 곳
│   │   ├── 각각의 module  - 액션, 액션 생성 함수, 리듀서
│   ├── hooks - Custom Hook, useSelector, useDispatch로 리덕스 상태 Get  
│   ├── pages
└───└── utils
├── app.tsx
├── index.tsx
├── index.html
├── package.json
├── tsconfig.json
├── eslint.json
└── webpack.config.ts

프로젝트 기술 스택

프로젝트 기술 스택은 아래와 같이 결정되었습니다.

Spec
DescriptionTypeScriptReactReduxStyled-ComponentsStorybookSocketIO

결론

Atomic Design 패턴을 그냥 맹목적으로 도입하지 않고 장단점을 판단해 일부는 적용하고, 일부는 적용하지 않고 사용해 보았습니다.
앞으로 기술을 사용할 때, 이 기술을 왜 쓰는지, 기술의 장단점이 무엇인지 파악하고 사용하는 개발자가 되도록 노력해야 겠습니다.

post-custom-banner

2개의 댓글

comment-user-thumbnail
2021년 6월 19일

잘 보고 가요~

답글 달기
comment-user-thumbnail
2021년 8월 27일

감사합니다.

답글 달기