Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

파일 구조 방법론 #1

Open
yjkwon07 opened this issue Oct 3, 2020 · 0 comments
Open

파일 구조 방법론 #1

yjkwon07 opened this issue Oct 3, 2020 · 0 comments
Assignees
Labels
🙋🏼‍♂️Discussion 같이 논의가 필요가 있을 때 표시

Comments

@yjkwon07
Copy link

yjkwon07 commented Oct 3, 2020

React Architecture Desgin

image

  • UrLink Ver1을 개발하면서 어려웠던 부분이 컴포넌트 분리를 어디까지해야 하는지 어려움이 있었다.
  • page를 구성할 때, HistoryItem이 CategoryItem으로 Drag&Drop(DnD)할 때, 각 컴포넌트에 FechData와 state 변화를 주어야 했다.
  • category, card 영역마다 경계를 주어 다른곳을 클릭하면 모든 작업을 reset하는 액션을 주어야 했다.
  • 즉, 모든 영역은 개별성을 주면서도 종속 관계도 포함되어 개발에 어려움이 있었다.

  • ver2에서는 디자인 패턴을 참고하여 영역을 나누고, 각 컴포넌트의 종속은 redux로 관리하기로 했다.
    • 이전에는 conetextAPI를 사용했지만, redux로 전역 state를 관리하는것과 동시에 비동기 호출을 redux-saga로 유지보수 쉽게 관리가 되는지 리팩토링 작업을 하면서 확인할 계획이다.

폴더 구조 시 고려해야할 사항


  • 리덕스, 리덕스 사가 관리 폴더 구조 생각해야함
  • material-ui 커스텀 해야하는 상황이 생기므로 각각의 컴포넌트 폴더에 추가적으로 생성해야 함
  • 처음 구조를 잡은 뒤 변경할 점이 생기면 그 때 변경해야할지 다시 결정 하는것이 Best라고 생각함.

Ver1. 폴더 구조

  • 컴포넌틑를 구성해야 할 때, 폴더를 생성하는 기준, 대표 이름 정하기가 너무 까다로움(명확한 솔루션 찾기가 힘듬)
  • 이전 폴더 구성은 DnD할 때 반응해야할 컴포넌트와, 다른 영역 클릭 시 해당 영역 활동 사항을 reset으로 표현해야할 컴포넌트들을 묶어서 관리했다.

image

|- components/
|    |- category/
|    |    |- styles/  => material-style-custome
|    |    |   |_ List.js
|    |    |   |_ Item.js
|    |    |   |_ DragDrop.js
|    |    |
|    |    |_ AppBar.jsx  // material UI 구성
|    |    |_ Drawer.jsx
|    |    |_ History.jsx  // material + animation UI 구성
|    |    |_ Card.jsx  // material + animation UI 구성
|    |      ...
|    |
|    |- popover/
|    |    |- styles/
|    |    |   |- Alarm.js
|    |    |_ Alarm.jsx
|    |      ...

프로젝트 탐색

  • GitHub에서 수많은 project 폴더구조를 보고 느낀 바, CaseByCase로 적용을 하는것 같다.
  • 프로젝트 규모, 기간, 확장성을 고려하여 구조를 짜는듯 하다.
  • 대부분 대표 폴더 구조는 아래와 비슷한 구조였다. (TypeScript는 제외했다.)
    • 더 많은 폴더 구조는 HOC, layout, template까지 구성한 프로젝트도 있었다.
asstes - 이미지, css, scss .. etc
components - 컴포넌트
containers - redux, 비동기 호출 함수 생성
pages - 컴포넌트와 container, template(선택사항) 조합
redux
saga
hooks
utils
...
  • pages에서 template과 components를 구성하고
  • container에서 redux, saga를 내려 받아 API 비동기 호출, 전역 state를 props로 내리는 구조를 많이 사용한다.
  • 그렇다면 components 구성은 어떤식으로 할까?
    • 이것 또한 너무 다양했다. (라우터(도메인) + 기능 + 공통)
    • 라우터의 이름이 대표하는 폴더이름으로 명칭하기 쉽고 그 안에 컴포넌트들을 구성할 수 있다.
    • 라우터 이외의 Header, Footer, Modal, 여러 컴포넌트들을 폴더로 만들어서 관리하고
    • 그 밖에 자주사용하는 컴포넌트들을 공통으로 분리하게 된다.
      image

아토믹 디자인

  • 아토믹 디자인(원자 - 분자 - 유기체 - 템플릿 - 페이지)
  • 아토믹 디자인이 조금 더 컴포넌트를 나눌 때 도움이될거라고 생각이 들었다.
  • 하지만, 아토믹 또한 모호한 면이 생기게 되었고 LINE Entry 📹에서 아토믹 디자인을 좀 더 유연하게 쓴 사례를 보게되어 다시 정립하게 되었다.

image

Atom

  • 원자 단위에서는 Button, h1과 같은 쪼갤 수 없는 단위를 말한다.
  • 만약 CustomButton, LinkButton이 생기게 된다면 폴더를 하나로 합쳐야 할까?
    • A: 현재는 폴더를 따로 가야하는게 맞는거 같다 if문 같이 분기를 타고 리턴하는것은 나중에 유지보수 시 찾기 힘들경우가 많을듯 하다.

Molecule, Organism => Organism

  • 분자는 Atom 2개 이상의 구성된다.
  • 유기체는 분자 혹은 Atom를 구성하는 단위.
  • Organism과 Molecule은 너무 모호한 면이라고 생각한다.
    • 작은 Card 영역을 Molecule로 생각할 수 있지만, 그렇다면 Card에 많은 Atom을 넣게 된다면 Molecule 영역에서 Organism으로 넘어가야 할까? 그렇다면 프로젝트에서 작업 중 Molecule과 Organism 영역에 깊은 고민에 빠지지 않을까?
      • A: Atom을 구성한 요소는 모두 Organism 영역으로 생각하게 되었다.
      • 반복되는 List, 하나 의 Item 들을 모두 구성하는곳이라고 생각하면 될거 같다.

Template

  • 컴포넌트를 구성하는 레이아웃 틀

Page

  • Atom + Organism + Template 을 구성하는 최종 UI 페이지

아토믹으로 적용시 고려해야할 점

  • Category, Card, Drag&Drop은 어디서 적용해야 할까? => Organism
  • state는 어떤식으로 주입해야할까? => container에서 내려 주는 구조
  • Alert은 어디로 속하는가? => Organism
  • layout은 어디로 속하는가? => Template
  • template과 layout은 같은 것인가? => same
  • 이용 약관 모달같이 커스텀 모달은 어디로 속하는가? => Organism

폴더 설계

  • 프로젝트 탐색후 우리 프로젝트에 적합한 폴더구조를 생각해 보았다.
  • 페이지 구성
    • 가입전 메인 welcome 화면
    • 로그인
    • 회원가입
    • 메인
  • 확장자
    • 리액트 컴포넌트를 리턴하는 파일은 jsx, 그 이외는 js로 통일한다.
  • ContainerComponent - Presentational component
    • container에서 전역 state 및 비동기 호출하는 함수를 만들어 자식 컴포넌트에 내리는 구조를 만든다.
  • asstes 폴더: 이미지, 전역 스타일을 관리하는 폴더
  • hooks 폴더: 공통으로 자주 쓰는 hooks를 관리하는 폴더
  • pages 폴더: container + template + components 를 구성한 페이지
    • containers를 따로 분리하여 관리하는 구조가 많았지만, 페이지에서 container를 정의하고 사용하는게 더 유지보수적으로 좋다고 생각한다.
    • container를 다른곳에서 재사용할까? 생각할 때는 현재 프로젝트에서 보이지 않으며 중복성이 보이면 hooks로 관리하는것도 방법이라고 생각한다.
    - home
    - welcome
    - login
    - register
    
  • components 폴더: atoms, organism, template
  • utils 폴더: 이전 프로젝트에 common과 같은 성격이라고 생각하면 된다.(명칭 바꿈)
    - validation/ => 유효성 검사를 하게 될 때 체크하는 파일을 둔다. validation 사용하는 컴포넌트 파일 이름으로 기준
                   => formik같은 유효성 검사 컴포넌트를 사용하게 된다면 상관없지만 현재는 있다고 가정
    - http.js // axios같이 HTTP 통신 세팅을 한다.
    
  • redux 폴더: api domain, chromAPI domain 명칭에 따른 폴더
    • 해당 폴더 안에는 api, action, rducer, index, saga로 구성한다.
    • api를 하나로 묶지않고 redux 안에 개별적으로 관리하게 된다면 쉽게 api를 쉽게 찾을 수 있으며, 유지보수 하기가 쉽다고 느껴졌다.
    - alarm
      - api // return promise
      - action
      - reducer
      - index // export reducer.js, saga.js
      - saga
    
  • store 폴더: redux의 index들을 묶어 combineReducer와 rootSaga를 만들어 middleware를 구성한 store를 export 한다.
  • App.jsx: router 정의를 한다.
  • index.js: provider, store, state를 전역으로 관리할 로직을 모두 포함한다.
src/
|- asstes/ => 이미지, 전역 스타일을 관리하는 폴더
|    |- images/ => 이미지 파일 담아둠
|    |- mui/ => 전역으로 다루는 material-ui-custom
|
|- pages/ => container + template + components 를 구성
|    |- home/
|    |    |- hooks/
|    |    |- style/
|    |    |- container/
|    |    |   |- Category.jsx
|    |    |   |- Card.jsx
|    |    |   |- History.jsx
|    |    |   |- Alarm.jsx
|    |    |   |_ Profile.jsx
|    |    |
|    |    |_ index.jsx
|    |
|    |- welcome/
|    |- login/
|    |_  register/
|
|- components/
|    |- atoms/
|    |    |- Button/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |
|    |    |- NewTabIcon/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |_ ...
|    |
|    |- organism/
|    |    |- CategoryItem/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |
|    |    |- CategoryList/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |
|    |    |- CategoryDrawer/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |_ ...
|    |
|    |- template/
|    |    |- NavBar/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |
|    |    |- Home/
|    |    |   |- styles/
|    |    |   |_ index.jsx
|    |    |_ ...
|    |_ ...
|
|
|- hooks/ => 공통으로 자주 쓰는 hooks를 관리하는 폴더
|    |_ useEventListener.js...
|
|- utils/
|    |- validation/ => 유효성 검사를 하게 될 때 체크하는 파일을 둔다. validation 사용하는 컴포넌트 파일 이름으로 기준
|    |_ http.js... // axios같이 HTTP 통신 세팅을 한다.
|
|- redux/
|    |- alarm/
|    |    |- api.js // return promise
|    |    |- action.js
|    |    |- reducer.js
|    |    |- index.js // export reducer.js, saga.js
|    |    |_ saga.js
|    |
|    |- user/
|    |- category/
|    |- url(link)/
|    |- history/
|    |- ws/
|    |_ another redux/...
|
|- store/
|    |_ index.js // combine, rootsaga, middleware 구성
|
|- App.js // router 정의를 한다.
|_ index.js // provider, store, state를 전역으로 관리할 로직을 모두 포함한다.

결론

  • 리액트 구조화를 누군가가 정립했으면 한다. 🙃

참고 사이트

@yjkwon07 yjkwon07 added the 🙋🏼‍♂️Discussion 같이 논의가 필요가 있을 때 표시 label Oct 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🙋🏼‍♂️Discussion 같이 논의가 필요가 있을 때 표시
Projects
None yet
Development

No branches or pull requests

3 participants