[Refactoring] Chapter1. 폴더구조를 바꿔보자

rlorxl·2024년 8월 26일
0

회고

목록 보기
3/7
post-thumbnail

실무를 경험하며 굴러가는 코드에서 끝이 아닌 유지보수와 협업하기 좋은 코드에 관심이 많아졌다.

특히 선언적인 코드와 리액트 설계의도에 관련된 강의를 듣고 깨달은게 많았고 내가 했던 프로젝트에 적용해봐야겠다고 생각이 들어서 1년도 더 된 토이 프로젝트의 코드를 한번 뒤집어 까보고 기록을 남기려고 한다.

코드의 양이 엄청 많지는 않았지만 1년반 전과 나의 눈이 조금 달라져서인지 지금 기준으로 코드가 더러워보이는 부분이 많았고 어디서부터 손을 대야할지 고민이 됐다.

거의 모든 코드를 결벽증 수준으로 싹 뜯어고치는 것은 무의미하다고 생각해 내가 생각하는 기준대로 전체적으로 수정할 부분은 전체적으로 수정하고, 부분적으로 수정할 부분은 부분적으로만 리팩토링을 진행해보기로 했다.

적용할 리팩토링의 목록을 나열해봤다.

  1. 폴더구조 재정의
  2. 코드 정리
    • 안쓰는 코드, 주석제거, import구문의 정리
  3. 명확한 이름
    • 모호한 함수명, 변수명을 일관되고 이유있는 이름으로 바꾸기
    • 상수화하기
    • 조건부 렌더링의 조건을 변수화하기
  4. 코드 리팩토링
    • 중복코드 추출, 긴 함수 리팩토링
    • 조건문, 반복문 리팩토링
    • 플래그인수 있으면 제거
  5. 선언적인 코드
    • useQuery요청을 선언적으로 사용하기
    • 로딩처리 선언적으로하기 (isLoading => suspense)
  6. 관심사의 분리 & 컴포넌트 추상화 수준 높이기
    • 컴포넌트 분리하기 (도메인 / 공통)
    • 도메인 전용 로직을 커스텀 훅으로 분리하기
    • 공통 로직을 유틸함수로 분리하기
  7. 일관된 에러처리
  8. 그 외 Reactivity지키기
    • 불필요한 상태 동기화
  9. 테스트코드 추가

여기서 내 기준으로 1,2,3번에 해당하는 항목이 가장 기본적인 리팩토링이자 중요한 밑거름단계가 될 항목이고,

5,6번에 해당하는 항목은 리액트의 설계의도를 지키는 코드로 리팩토링할 핵심 항목이다. 5,6번은 어떻게 보면 선언적인 코드라는 같은 맥락으로 볼 수도 있을것 같은데 6번 항목이 좀 더 관심사의 분리로 가독성, 유지보수하기 좋게 리팩토링하는 단계라고 볼 수 있다.

그리고 나머지는 앞의 항목보다는 부가적인 요소로 조금 더 좋은 코드로 가기 위한 고민과 함께 코드를 고쳐볼 것이다.


먼저 폴더구조부터 다시 재정의에 들어갔다.

기존 폴더구조.

나름의 규칙성을 가지고 폴더구조를 정의한건 맞는데 몇가지 모호한 부분들이 있었다.

1. 흩어진 공통파일

lib, util, types와 같은 폴더들이 흩어져있고 lib, util폴더 내부의 항목들이 파일 구분이 불명확해서 명확한 구분이 필요했다.

수정 전

  • lib: 라이브러리와 관련된 파일, 상수 파일들이 혼재.
  • util: 유틸함수.
  • types: 공통 타입들, 컴포넌트 타입들이 혼재.
src
┗ types
	┣ create-type.ts
	┣ data-type.ts
	┣ modal-type.ts // Modal에서 사용하는 types
	┗ index.ts // Keywords에서 사용하는 types

수정 후

common폴더를 생성해 라이브러리 관련 폴더 등 흩어진 파일들을 한데 모았다.

  • lib: 라이브러리와 관련된 파일.
  • util: 유틸함수만 포함된 폴더.
  • types: 공통 타입은 common/types로 이동하고 컴포넌트에 종속된 타입은 컴포넌트가 속한 폴더 하위의 types.ts파일을 생성.
  • consts: 상수관련 파일들을 분리하기 위해 새로 생성.

2. 컴포넌트

기존에 컴포넌트 파일은 페이지가 라우팅되는 기준으로 나뉘어져 있었다.

사진상엔 3개 파일만 존재하지만 10개 이상이 되었을 때는 알아보기 어려운 문제가 있었다.

대표 라우팅되는 페이지 내부로 디테일 페이지가 존재하거나 특정 관련 주제로 묶이는 컴포넌트들이 존재하면 디테일 페이지나 특정 관련된 폴더를 하위에 만들어 컴포넌트들을 따로 위치시켰다.

그리고 가장 최상위에는 해당 페이지의 메인에 위치하는 컴포넌트들과 해당 페이지에서 사용하는 공통 컴포넌트를 위치시켰다.

수정 후

수정 후에 컴포넌트들이 어디에 위치하는지, 어떤 컴포넌트인지가 파악이 쉬워졌고 리팩토링시 컴포넌트 분리를 진행하면서 기존보다 더 세세한 컴포넌트 분리가 이루어졌는데 이 때 파일을 생성하기가 더 용이해지는 장점이 있었다.

3. 목적에 맞는 폴더 생성과 이동

1. styles/global-layout.tsx → layout/main-layout.tsx

styles폴더 안에 공통 레이아웃 파일이 존재했다. 레이아웃 파일과 목적성이 맞지 않다고 생각해 layout이라는 폴더를 따로 생성하고 공통 레이아웃과 관련된 파일들을 위치시켰다.

2. hooks/suspense.tsx → pages/suspense.tsx

suspense파일은 react suspense를 반환하는 provider역할을 담당하는데 hooks는 단지 커스텀 훅 파일들만 모아놓았기 때문에 관심사가 다르다고 생각해 pages폴더의 루트로 이동시켰다.

next.js의 pages의 루트에는 원래 404나 도큐먼트 파일이 위치한다. suspense를 이 위치에 이동한 이유는 error-boundary와 함께 프로젝트 최상단에서 공통적으로 사용되는 파일이자 provider라고 생각했기 때문이다.

3. util/request.ts → service/request.ts

request는 API요청함수를 담당하는 파일이다. 기존에는 service폴더가 없어 util폴더에 애매하게 위치해 있었는데 request파일과, 추후 query관련 함수를 분리하기 위해 service폴더를 따로 생성했다.

4. 전체 폴더구조

전체 폴더구조는 이렇게 마무리되었다.

기존에 폴더구조의 구분이 페이지별로 크게만 나뉘어져 있었는데 프로젝트의 복잡도가 높아짐에 따라 한 폴더안에 파일이 많아지고 점점 일관된 기준이 없어지고 불명확해진다는 문제가 있었다.

때문에 수정 후에는 파일들을 페이지 단위보다는 하위폴더로 도메인과 결합된 주제, 종류별로 나누었는데 개인적으로 폴더의 깊이가 3단이상 생성되는것을 선호하지 않아 그럼에도 위치가 모호한 파일들이 항상 하나씩은 나오게 되었던것 같다.

또한 next12버전의 페이지 라우터를 사용중이라 pages폴더는 정해진 규격에 맞춰 폴더를 정리할 수 밖에 없는 제한이 있어 모든걸 일관되게 할 수는 없었다.

정리하면 폴더구조는 프로젝트 초기에 복잡도가 높아질 것을 대비해 작은 도메인별로 나누는게 좋을 것 같다. 하지만 모든 상황에 딱 들어맞는 일관된 구조로 정의하고자하는 생각보다는 나중에 돌아봤을 때 유지보수하기 괜찮은 정도로 설계하는게 적당하다고 생각한다.

0개의 댓글