소분소분 회고(3) - 프로젝트 셋팅 및 협업 전략 세우기

kind J·2022년 12월 11일
0
post-custom-banner

나는 소분소분 서비스의 본격적인 프론트엔드 개발에 앞서 프로젝트 셋팅와 레이아웃 잡는 것을 맡아서 했다.

이전에 만들어 본 개인 프로젝트에서 쓴 리액트 + Typescript 에 적합한 Foundation 을 기반으로 하였다.

📂폴더구조

src 폴더 안쪽이 본격적으로 작업이 이루어지는 공간이라고 할 수 있다.


1) apis

apis 는 http 요청들을 관리하는 폴더이다.

client.ts 파일에는 요청마다 필요한 기본값 설정을 담은 axios 인스턴스를 만들었다.

const axiosApi = () => {
  const instance = axios.create(baseSettings)
  return instance
}

const axiosAuthApi = () => {
  const instance = axios.create({
    ...baseSettings,
    headers: { SOBUNSOBUN: `${localStorage.getItem('sobunsobun')}` },
  })
  return instance
}

export const defaultInstance = axiosApi()
export const authInstance = axiosAuthApi()

axiosApi 는 사용자 인증이 필요 없는 요청을 보낼 때 쓰는 인스턴스이고,
axiosAuthApi 는 사용자 인증이 필요한 요청을 보낼 때 쓰는 인스턴스이다.


2) assets

assets 은 svg 와 image 파일들을 모아둔 곳이다.

export { ReactComponent as SearchIcon } from './search.svg'
<SearchIcon className={styles.searchIcon} />

svg 파일들은 ReactComponent 방식으로 가져왔다. 그래야 class name 을 넣을 수 있고 svg의 색도 바꿀 수 있어서, 모양은 같은데 색만 다른 svg는 css 로 컨트롤 할 수 있게 된다.
또한 svg 용량이 작으면 자동으로 js 파일에 박아서 다운 받아주기 때문에 랜더링 시간이 단축되는 장점이 있다.

import fruit from 'assets/images/fruit.png'

export const IMAGE_PATH = {
  fruit,
} as const

image는 경로를 변수로 지정하여 import 해서 React 컴포넌트에서 사용할 수 있도록 하였다.


3) components

컴포넌트 폴더에서는 공통으로 쓰는 컴포넌트 위주로 분리하였다.


4) hooks

hooks 폴더 안에는 Custom hook을 모아놨는데, debounce 나 modal 같이 여러곳에서 쓰는 훅 뿐만 아니라, http 요청을 할 때 사용했던 useQuery를 hooks 으로 감싼 것도 있다. 재사용의 목적도 있지만 http 요청이 필요한 페이지 컴포넌트 안의 코드량이 방대해짐을 막기 위함도 있다.


5) pages

pages 폴더는 는 route에 따라 랜딩되는 페이지 컴포넌트들을 두었다.

참고로 내가 맡았던 게시글 생성 페이지에서만 쓰는 컴포넌트들은 src/components 의 컴포넌트로 분리하는 것이 아니라 Posting 폴더 안쪽에 두었다.
게시글 생성 페이지에서만 쓰기 때문에 page 와 함께 두는 것이 가독성과 유지보수 측면에서 좋다고 생각했기 때문이다.


6) recoil

recoil 폴더에서는 전역상태로 관리될 state를 모아두었다. 전역상태 관리를 위해 recoil을 썼기 때문에 recoil 이라고 명명하였고 만약 리덕스와 병행해서 쓰게 된다면 state 로 바꿔도 좋을 것 같다.


7) routes

route 는 url 이 달라질 때 보여질 페이지 컴포넌트들을 볼 수 있다.

const RootRoute = () => {
  return (
    <div className={styles.app}>
      <Routes>
        <Route path='/' element={<Layout />}>
          <Route path='' element={<Splash />} />
          <Route path='intro' element={<Intro />} />
          <Route path='login' element={<Login />} />
          <Route path='local' element={<LocalAuth />} />
          <Route path='signup' element={<Signup />} />
        </Route>
    </div>
  )
}

export default RootRoute

8) styles
Style 은 SCSS로 작업하기로 했기 때문에 SCSS파일들이 있다.

base 폴더 안에는 reset 파일 같은 기본 설정 파일이 있고
constants 에는 color나 fonts, 미디어쿼리 구간과 같은 변수들을 모아놓았다.
mixins 는 flex 설정이나 font-size, 각종 수치들을 vw로 계산하여 반응형 웹 만들 때 도움을 주는 계산식을 모아 두었다.


9) types
types 는 타입들을 관리한다.


10) utils
utils 함수와 배열들을 모아놓은 폴더이다.


📂팀 전략 세우기

여러명이 협업하는 팀 프로젝트인 만큼 효율적인 버전관리와 일관성 있는 코딩 스타일을 갖추기 위해 깃 버전관리 방법, 커밋 컨벤션, 각종 린터 및 프리티어 설정, 코드 컨벤션을 정하였다.


1) 깃 버전관리 및 협업 방법
프론트엔드와 백엔드에서 공동으로 사용할 SobunSobun 이라는 organization 을 만들었다.

새롭게 작업하는 브랜치는 앞에 feat를 붙여서

feat/home

이런식으로 이름을 붙였다.

이미 생성된 페이지 혹은 컴포넌트를 수정하는 브랜치는 앞에 'fix' 을 붙였다.

기능 구현이 마무리 되면 dev로 풀리퀘를 날렸고, 팀원들이 검토해서 보완할 부분은 코멘트를 남기고 머지 해주는 식으로 진행하였다.


2) 린터 & 프리티어
eslint에서는 마지막 줄에 라인 추가, semi 여부, import 순서 등을 정하였다.
prettier에서는 줄바꿈 폭 길이, 탭너비, 세미콜론 사용 여부, 줄바꿈 방식 등을 설정하였다.
stylelint 에서는 css 순서, name pattern 등을 정하였다.


3) 커밋 컨벤션
커밋을 할때 간단하게 어떤 작업을 했는지 표시하였다.

  • feat : 새로운 기능 추가
  • fix : 버그 수정
  • docs : 문서 수정
  • style : 코드 포맷팅, 세미콜론 누락, 코드 변경이 없는 경우
  • refactor : 코드 리펙토링
  • test : 테스트 코드, 리펙토링 테스트 코드 추가
  • chore : 빌드 업무 수정, 패키지 매니저 수정

4) 코드 컨벤션

  • 폴더명 : PascalCase
  • .tsx : PascalCase
  • .scss : CamelCase
  • class 명 : CamelCase

5) CSS Module 사용
컴포넌트를 스타일링 할 때 CSS Module 이라는 기술을 사용해서 CSS 가 중첩되는 것을 방지하였다.


6) classnames 라이브러리 사용

classnames 를 이용하여 조건을 주어 클래스명을 넣고 빼도록 하였다.


초반에 프론트 개발자들과 stack 은 어떤것을 쓸지, 코딩 규칙은 어떻게 할지 논의하고 폴더 구조 등을 미리 잡아놔서 기획하고 디자인 시안이 나왔을 때 바로 개발에 착수할 수 있어서 시간을 단축할 수 있었다. 초반에 확실히하게 컨벤션과 폴더 구조를 잡고 기본 셋팅을 해보고 빠르게 가이드를 주는 주었던것이 협업하기 좋은 환경을 만들어 준 것이라고 생각한다.

이전에 수행했던 팀 프로젝트에서는 나서서 무언가 하기보다는 누가 하자는 대로 따라갔었는데, 이번에는 주도적으로 프로젝트 셋팅을 할 수 있어서 보람있었고 뿌듯했다.

profile
프론트앤드 개발자로 일하고 있는 kind J 입니다.
post-custom-banner

0개의 댓글