최근에 리액트를 사용하여 개발을 하면서 초창기에는 깊게 고민해보지 못했던 프로젝트 설계에 대한 고민을 팀 프로젝트라는 계기로 다른 사람들과 이야기해볼수 있었던 기회가 있었다.
팀원과 이야기를 하면서 고민했던 내용들은 다음과 같다.
처음에는 컴포넌트에 대한 고민이었다. 리액트를 라이브러리라 지칭하는만큼 정해진 패턴이 없고 너무나도 자유롭기 때문에 컴포넌트 설계에 대한 통일성이 필요했다.
그래서 이번 프로젝트에서는 Presentational and Container Components 패턴을 따르기로 했다. Atomic design이라는 패턴도 존재하지만 디자인이 자주 변경될 가능성이 있어 배제하였다.
이 패턴을 따른 이유는 관심사 분리로 코드의 재사용이 유리하고 데이터의 흐름을 좀 더 명확하게 파악할 수 있기 때문이었다. 결과적으로 이렇게 패턴을 정해놓고 개발을 시작한 덕분에 나의 코드 뿐만 아니라 서로간의 작성한 코드의 흐름도 따라가기 쉬워 유지, 보수 측면에서 편리했고 이해하기 수월했다. (사실 hook이 나온 이후로는 잘 사용하지 않는 패턴이라고 한다.)
그 다음은 디렉토리 구조에 고민이었다.
사용되는 기술스택에 따라 조금씩 구조는 달라지겠지만 리액트 공식문서에서 권장하는 구조로 파일의 기능이나 라우트에 의한 분류로 설계하고 자주 함께 변경 되는 파일끼리 묶어 설계한 디렉토리 구조는 다음과 같다.
┌── public/ - favicon, html
├── src/
│ ├── api/ - api 폴더 (공통적인 instance 관리)
│ ├── types/ - type 폴더
│ │
│ ├── assets/ - assets 폴더
│ ├── components/ - 컴포넌트 폴더 (Presentational Components)
│ │ └── componentName/ - 컴포넌트별 폴더
│ │ └── componentName.style.ts - 컴포넌트 style 정의
│ │ └── index.tsx - index.tsx 정의
│ │
│ ├── constants/ - constants 폴더 (매직넘버 관리)
│ │
│ ├── container/ - 컨테이너 폴더 (Container Components)
│ │ └── containerName/ - index.ts를 정의
│ │
│ ├── store/ - redux toolkit 폴더
│ │ └── root.ts - store 정의
│ │
│ ├── hooks/ - 사용자 정의 hook
│ │
│ ├── pages/ - 라우터 정의 폴더
│ │ └── MainPage.tsx
│ │
│ ├── styles/ - 글로벌 스타일 폴더
│ │ └── globalStyle.ts
│ │
│ └── utils/ - 유틸 폴더
│ └── index.ts
│
└── package.json
프로젝트 설계를 위해 팀원과 이야기를 하면서 그동안 혼자 개발해오면서 프로젝트를 시작할 때 그저 사람들이 많이 사용하는 방식을 따라가기에 급급했고 왜 이런 방식을 사용했는지에 대한 고민을 해보지 못한 것에 아쉬움이 있기도 했고 설계는 개발자의 취향과 기준에 의한 것이라 절대적인 설계는 없기 때문에 정답을 찾기 어렵지만 지속적으로 프로젝트 설계에 대해 고민하여 더 나은 설계를 할 수 있도록 노력해봐야겠다는 생각이 든다.