Preview
React를 배우면서 좋았던 점은 라이브러리라는 점이다. 단점은 라이브러리라는 점이다.
프로젝트마다 특색이 다르기 때문에, 아키텍처 구성이 달라질 수 있어 프론트 작업 시 자유도가 높아질수록 해당 프로젝트의 맞게 아키텍처를 구성할 수 있었다. 하지만, 자유도가 높아짐에 따라 폴더구조와 컴포넌트 사고방식을 생각하는 시간 비용이 상당히 높았다.
처음으로 리엑트 프로젝트 도입한 시점에서는 페이지도 단순하고 리액트를 사용에만 집중을 가졌다. 하지만, 점차적으로 페이지가 늘어나고, 계속해서 컴포넌트 분리를 하고 해당 컴포넌트를 어디 폴더에 넣을지 고민이 커졌다. 이슈 처리에만 집중을 하고 싶은데 계속해서 부가적인 요인으로 나를 너무 괴롭혔다.
그래서 나만의 컴포넌트 분리 방식과 폴더 아키텍처 방식을 만들어 공통 아키텍처 구분을 만들기로 했다. 여기서 내가 고민이 큰 이슈들을 나열해 보았다.
- 컴포넌트 모듈화를 통해 블럭 쌓기처럼 내가 원하는 페이지를 자유롭게 연결시킬 수 있다고 배웠지만, 해당 컴포넌트는 과연 다른 페이지에 재사용하는 빈도가 높을까?
- 컴포넌트 폴더와 페이지 폴더를 따로 만들게 되면 페이지에 해당되는 컴포넌트 수정 요청 시 빠르게 해당 컴포넌트를 찾을 수 있을까?
- 비즈니스 로직을 해당 컴포넌트에 넣게 되면 api 교체 혹은 수정이 발생시, 해당 컴포넌트는 쉽게 수정이 가능한가?
이것을 다시 요약을 해보았다.
- 공통 컴포넌트를 추출 할 수 있는가?
- 페이지와 분리된 컴포넌트 찾기가 용이한가?
- 유지보수에 용이한가?
- 비즈니스 로직과 분리가 되어 있는가?
컴포넌트 분리하기
- 컴포넌트 페이지 폴더 생성
- index 파일에 모든 컴포넌트 작성하기
- 분리될 수 있는 컴포넌트 찾기 (최적화)
- 페이지에서 분리된 컴포넌트는 해당 페이지 폴더에서 컴포넌트 폴더를 만들고 index로 모듈화 구조 만들기
- 여러 페이지에서 분리된 컴포넌트를 사용하게 된다면, 공통 컴포넌트 폴더 이동
- 때에 따라 페이지 폴더에서 공통 컴포넌트 폴더를 만들어 사용할 수 있음(선택)
Atomic Design?
결론: Atom 단위 혹은 디자인 시스템은 사용가치가 있지만, 그 이외는 사용 안 함
처음에는 아토믹 디자인을 보고 해결점을 찾은 듯했다.
하지만, Molecules, Organisms 경계 부분이 너무 모호해 분리하는 부분부터 힘을 쓰게 되었다.
- 즉, 개발하기 전부터 컴포넌트 단위를 쪼개는데 시간이 너무 많이 들게 되었다.
- 또한, 컴포넌트를 분리하게 되었다고 생각했을 때, 막상 개발하게 되면 다시 Molecules 혹은 Organisms이 맞는지 의구심이 들게 되었다.
Folder architecture
해당 폴더구조는 Nextjs에서 pages폴더가 router 생성 관련으로 페이지를 파일 구조로 만들어야 했기 때문에 views라는 폴더를 만들어 앞에서 말한 pages 개념이 적용되었다고 생각하면 된다.
|-- comonents => 공통 컴포넌트 관리
|-- hooks => 공통 hooks 관리
|-- layouts => 레이아웃 틀 컴포넌트 관리
|-- modules => api feature 단위 관리
|-- pages => router 페이지 관리(Head 정보및 SSR 관리)
|-- public => assets 파일 관리
|-- typings => declare, global 타입 관리(컴포넌트는 해당 파일 안에서 interface 타입으로 관리)
|-- utils => 중복 로직 함수들을 pure 함수화 하여 util 파일 관리
|-- views => pages 폴더에서 사용하는 페이지 뷰 컴포넌트 관리(일반 페이지 파일과 같다)
components
공통으로 사용되는 컴포넌트를 components 폴더에서 관리를 한다. 또한 대표 컴포넌트 안에서 부분 컴포넌트(도메인)를 만들경우 해당 폴더 아래에서 폴더로 만들어 관리를한다.
hooks
ui를 다룰 때 사용하는 action 핸들링을 hooks로 관리를 할 때, 다른 컴포넌트에도 사용할 수 있으므로 이러한 경우에 hooks 폴더에서 관리를 한다.
layouts
기본 레이아웃을 구성하는 것은 BaseLayout을 만들고 해당 틀외에 레이아웃들도 layouts 폴더에 관리를 하게 된다.
또한, BaseLayout에서 파생된 레이아웃들도 layouts 폴더 아래에서 생성한다.
modules
modules 같은 경우 api 요청 시 feature 단위로 폴더를 만들고 관리를 한다.
- @types 폴더는 modules에서 공통으로 사용되는 타입을 정의한다.
- client 폴더는 axios, fetch 같은 초기 세팅을 다루는 곳이다.
- feature 단위 폴더는 다음 포스팅에서 더 자세하게 다룰 것이다.
pages, views
pages 폴더 파일내용은 views 폴더 영역을 불러오는 영역을 제외하고는 SSR, Head 영역을 구성한다.
views 폴더 영역에서는 페이지에서 보이는 영역을 구성하고 그 안에서 컴포넌트를 분리하게 될 경우 해당 컴포넌트 아래에 만들어서 사용하게 된다.
- utils, config 같은 폴더를 해당 페이지 영역 폴더에 구성할 수도 있다.
- utils 같은 경우 해당 페이지에서 공유되는 utils를 만들 때 사용한다.
- config 같은 경우 select option 배열 같은 설정 관련 변수들을 모듈화 하여 공유한다.
결론
현재 이 구조에서 CRA(Create-React-App), Nextjs 활용하여 실무에서 무난하게 사용하고 있으며, 타입 스크립트에서도 무리 없게 진행할 수 있었다.
단점으로는 내가 생각한 아키텍처이므로 협업에서 새로운 러닝 커브가 발생되었다. 하지만, 이것을 역으로 생각하면 서론에서 말한 유지보수성 아키텍처에 깊은 고민에 빠지게 될 것이라고 생각한다. 여기서 이 프로젝트를 공유하고 확장하는 게 더 괜찮다고 보고 있다.
명심할 것은 처음부터 컴포넌트를 분리를 생각하게 될 경우 머리만 복잡해진다. => 단순함에서 시작하자
- 하지만 실전에서는 또 고민하고 있을 수 도 있다...
code view
참고
부록
'urTweet' 카테고리의 다른 글
[modules] React + Data fetch handling (0) | 2021.11.22 |
---|---|
[setting] Atomic Design? (0) | 2021.11.20 |
[helper] Redux + Redux-saga (0) | 2021.11.12 |
[setting] Next + Redux (0) | 2021.11.11 |
[setting] Next + Typescript Environment Setup (0) | 2021.11.11 |