프로젝트를 진행할 때나 과제를 진행할 때마다 프로젝트의 규모가 다른 것도 있지만, 초기설정 설계방식이 달랐다. 당시엔 팀원들이랑 ‘빨리 초기설정을 하고 개발에 들어가자!’라는 마인드로 진행했지만 마음속으론 기획과 구조를 좀 더 체계적으로 계획하고 개발하고 싶은 마음이 있었다. 불충분한 설계로 프로젝트를 진행하였을 때 각자가 맡은 페이지, 컴포넌트의 폴더구조가 달라 다른 팀원이 봤을 때 이해하기 어려웠고 수정해야 할 부분들이 계속해서 생겼다. 그 점을 방지하고자 나만의 리액트 설계구조 가이드를 작성하여 공유해 본다.
리액트를 접한 지 이제 4개월이 되어간다. 위코드에서도 그렇고 공식문서에서도 처음 리액트를 공부할 때 CRA를 통해 프로젝트를 쉽게 시작할 수 있다고 하여 줄곧 CRA로만 리액트 개발을 해왔다. CRA 개발방식에 대해 첫 의문이 든 계기는 인턴 할 때 리액트 네이티브를 개발하면서였다. 네이티브를 expo로 처음 접했지만 정작 실무에서는 Native-Cli 로 모든 구조를 작성해야 했다. 리액트도 마찬가지로 이젠 webpack과 babel을 사용하여 초기 설정과 폴더구조를 직접 설계해야 할 것이다.
개발하면서 이런 고민을 빈번하게 했을 것이다.
💡 공용 컴포넌트에 다른 조건이 추가되어야 한다면 어떡하지..?
설계할 때 여기까진 생각 못 했는데 이 부분 또 수정 해야 하네..?
기획의 변화, 디자인 변경, 요청 사항 추가 등 적어도 한번은 계획했던 것과 달리 상황에 따라 대응하도록 수정해야 할 필요성이 생길 것이다.
하나의 함수, 변수, 클래스, 컴포넌트에 한 번에 너무 많은 일을 부여하게 되면 혼란에 빠지게 된다. 이러한 문제를 해결하는 방법으로 한 번에 한 가지만 하도록 단위를 나누는 것이다. 단위별로 하나의 관심사만 갖도록 하고 관심사에 대해서만 확실하게 동작하도록 만들어야 한다.
그렇게 되면 문제가 발생했을 때 전체 기능을 파악하기 위해 읽어야 하는 코드의 단위가 줄어들게 되고, 코드에 대한 파악이 빨라지므로 문제를 효과적으로 해결할 수 있게 된다.
이렇게 한 번에 한 가지만 걱정해도 괜찮도록 각각의 관심사에 따라 코드를 분리하는 기법을 관심사의 분리라고 부른다.
관심사의 분리가 적절히 구현된 코드에서는 낮은 결합도(각각의 코드가 서로 얽혀있지 않고 독립적으로 잘 분리되어 있음)과 높은 응집도(유사한 내용끼리 비슷한 위치에 잘 모여 있음)와 같은 특성을 발견할 수 있다.
장점
PROJECT
├── .vscode/
├── node_modules/
├── package.json
├── package-lock.json
├── .eslintrc
├── .prettierrc
├── .gitignore
├── README.md
│
├── public/
│ ├── images/ // 이미지 파일 폴더
│ └── data/ // Mock 데이터 폴더
│
└── src/
├── index.js
├── utils.js // 유틸함수 정의
├── constants.js // 상수데이터 정의
├── Router.js
├── components/ // 공통 컴포넌트 폴더
│ └── ComponentName/ // 공통 컴포넌트 별 폴더
│ ├── ComponentName.jsx
│ └── ComponentName.style.jsx // 컴포넌트 style 정의
│
├── pages/ // 라우트에 의한 분류 페이지 폴더
│ └── PageComponentName/
│ ├── PageComponentName.jsx
│ └── PageComponentName.style.jsx
│
├── styles/ // styled-component 스타일 폴더
│ ├── GlobalStyle.jsx
│ └── theme.js
│
├── redux/ // redux 폴더
│ ├── store.js // redux store
│ ├── actions/ // 액션 정의 폴더
│ └── reducers/ // 리듀서 정의 폴더
│
└── hooks/ // custom hook 폴더
프로젝트마다 사용하는 기술 스택에 따라 변경될 수 있지만, 현재 기본적으로 styled-components, react-router-dom, redux를 사용하는 기준에서 작성하였다.
나는 디렉터리 구조 설계 시 리액트 공식문서에서 권장하는 구조로 파일의 기능이나 라우트에 의한 분류로 설계하는 것을 지향한다.
PascalCase로 작성하고 그 이외는 camelCase로 작성한다.src/components 경로에 Nav, Button 등 폴더로 관리한다. 공통 컴포넌트는 충분한 소통을 통해 필요한 Props를 고려하여 작성한다.pages에서는 라우트에 의한 페이지별 컴포넌트를 작성한다. 각 페이지에서 개별로 필요한 컴포넌트는 각 페이지 폴더 안에 작성한다.styles 폴더는 styled-components의 전역 스타일, reset css, theme을 작성한다.ComponentName.style.jsx)을 생성하여 컴포넌트 파일에서 임포트 해서 사용한다. 스타일 파일을 분리함으로써 코드의 가독성이 올라간다.constants, util, hooks에 작성하여 임포트하여 작성한다.아직 많이 부족한 설계이지만 관심사에 따른 분리, 재사용성, 유지보수, 가독성 등 여러 요인들을 지속적으로 고민하여 같이 개발하는 사람들로 하여금 보일러 플레이트가 될 수 있는 구조를 설계해 보고 싶다.
현재 CRA 설계구조로 개발 중이지만 추가적으로 webpack, babel, TypeScript를 사용한 디렉터리 구조도 설계해 볼 계획이다.
구조 설계로 고민중이였는대 잘보고 갑니다!