[2022 HUFS 하계 모각코] 0803 TIL

KwakKwakKwak·2022년 8월 3일
0
post-thumbnail

맛집 리스트 리팩토링 - 폴더 구조 편

미니 해커톤 이후 리팩토링의 필요성을 느끼고 그간 짜왔던 코드들을 순서대로 살펴보면서 공부할 예정.

그 첫 번째 순서로 멋사 프론트엔드 트랙 마무리 과제였던 '맛집 리스트' 프로젝트 리팩토링이 되겠다.


우선 본인의 프로젝트 구조도를 먼저 살펴보겠다.

jmt-place
 ├ public
 | 	ㄴ img - flaticon 이미지들
 ㄴ src
 	├ index.js
	├ assets - atom.js
    |		 ㄴ Data.js
    |		 ㄴ Image.js
    ├ components - App.js
    |			 ㄴ Layout.js
    |			 ㄴ Loading.js
    | 			 ㄴ Pagination.js
    ├ models - EachMenu.js
    |		 ㄴ ShowMenuList.js
    ├ routes - Router.js
    |		 ㄴ NotFound.js
    ㄴ styles - GlobalStyles.js
    		 ㄴ LayoutStyles.js
             ㄴ MenuListStyles.js
             ㄴ MenuStyles.js

우선 src 폴더에서 가장 최상위 레벨에 index.js만을 남겨두고 나머지 파일들을 각 목적과 용도에 따라 폴더 별로 분류하려 하였다.

api를 통해 불러올 데이터를 모아놓을 Data.js, 프로젝트에 사용될 아이콘과 png이미지들의 주소를 모아놓은 Image.js 그리고 Recoil을 사용하기 위해 atom.js까지 모두 assets 폴더에 넣어줬다.

그리고 components, models, routes 세 폴더로 프로젝트 핵심 파일들을 분류해줬는데, 이는 사실 맛집 리스트 프로젝트 전까지 내가 생각하던 디자인 패턴은 아니다. 특히 routes 폴더가 그러한데, 프로젝트를 시작하기 전 노마드 코더의 트위터 클론 코딩 강좌를 수강하던 중 강의에서 나온 패턴이 App.js에서 Router 기능들을 전부 Router.js로 완전히 분리하여 관리했던 방식이어서 그것을 차용하여 사용해본 것이다.

지금 와서 생각해보면 굳이 routes 폴더를 따로 빼서 Router.js와 여타 다른 라우터 링크 파일을 뺄 필요가 있나 싶은 생각이 든다. 오히려 routes 폴더를 분기하는 이 방식이 생소한 것이다 보니 혼란을 야기했던 것 같다. App.js에 그렇게 많은 내용이 들어가는 것도 아니기 때문에 이 방식은 앞으로 채택하지 않을 것이다.

그리고 models 폴더도 노마드코더 강의를 보면서 채택한 패턴 중 하나였는데, 사실 저 model이라는 폴더명이 의미하는 바가 굉장히 모호해서 별로였다. 물론 components 폴더 안에 다 때려박는 것보단 낫지만, 차라리 EachMenu.js 나 ShowMenuList.js의 용도가 재사용에 중점이 있는 만큼 templates 등의 정확한 용어를 사용하는 것이 낫지 않았을까 하는 아쉬움이 있다. model이라는 명칭은 재사용 파일보다는 말 그대로 '데이터 모델' 등의 파일들에나 더 어울릴 것 같다.


내 프로젝트 디자인 패턴은 여기까지 보도록 하고, 맛집 리스트 과제를 제출한 다른 동료들의 코드들을 슬-쩍 염탐해보자(혹시라도 코드 주인분께서 이 글을 보신다면 너른 양해바랍니다..)

A)

 *
 ├ public
 | 	ㄴ assets - checkbox, remove.png
 ㄴ src
 	├ index.js
    ├ App.js
    ├ Loading.js
    ├ Context.js
	├ apis - api.js
    |	   ㄴ service.js
    ㄴ components
    	   ├ header - index.jsx / styled.js
           ├ navigation - index.jsx / styled.js
           ├ pages
    	   |	  ㄴ all ~ mypage - index.jsx / styled.js           
           ├ shared
    	   |	  ㄴ list, mylist, page - index.jsx / styled.js 
		   ㄴ template - index.jsx / styled.js

A님의 프로젝트 구조. 우선 모든 하위 폴더의 내용물이 index.jsx와 styled.js로만 이루어져 있어 굉장히 깔끔하다. 이러한 세분화 구조의 장점으로 각 index.jsx 파일의 코드 퀄리티가 상승하는 것을 목격했다. 코드의 길이도 길지 않으면서 딱 1파일에 1사용목적을 지키기 때문에 직관적이었다. 그리고 특이점으로는 Context Api를 사용하여 여러 상태 값을 관리하는 모습을 볼 수 있었다.


B)

 *
 ├ public
 ㄴ src
 	├ index.js
    ├ App.js
	├ images - 프로젝트에 사용된 이미지 svg파일들
	├ fonts - 프로젝트에 사용된 font들
    ㄴ components
        ├ Header.js
        ├ Mypage.js
        ├ Navbar.js
        ├ StyledComponent.js
        ㄴ Res   
    	   ├ ResItem.js
           ├ ResList.js
           ├ ResLoading.js
           ├ ResPagination.js
		   ├ ResProvider.js
           ㄴ ResSC.js

B님의 프로젝트 구조. 이 분도 간결하게 구성돼있었다. 특이한 점은 Res라는 폴더 하에 맛집 리스트 핵심 기능 파일들을 모아 놓았다는 점이다. 역시나 A님과 비슷하게 각 파일들마다 컴포넌트가 수행하는 기능과 관련 코드들이 잘 분기돼있어 한 눈에 파악하기 쉬웠다. 그리고 Context Api를 사용하여 CREATE - TOGGLE - REMOVE 3개 상태를 관리한 점도 동일했다.

여기까지 살펴봤을 때 굳이 내가 고민했던 Recoil이나 Redux같은 상태 관리 라이브러리를 사용하지 않아도 충분히 해결할 수 있었던 과제였던 것 같다. 그만큼 내가 기존에 익숙한 훅과 코드들만 사용하려 하는 관성이 있었다는 점도 캐치할 수 있었다.


C)

 *
 ├ public
 ㄴ src
 	├ index.js
    ├ App.js
	├ api.js
	├ atom.js
    ㄴ components
    |    ├ Header.js
    |    ├ Board.js
    |    ├ Heart.js
    |    ├ Pagination.js
    |    ├ CheckBox.js
    |    ㄴ Footer.js
	ㄴ routes   
         ㄴ Home.js

마지막으로 C님의 프로젝트 구조도. 어쩜 가면 갈 수록 간결해진다. 이 분은 우선 Recoil을 사용하셨다. 이 글에서 소개한 3개 프로젝트 중 가장 나의 코드와 비슷한 구조라 볼 수 있다(상위호환 ㅋㅋ). 맛집 리스트의 핵심 기능인 메뉴 선택, 좋아요, 삭제 기능을 Heart.js 파일에서 로컬스토리지를 활용해 한 번에 관리하고 있다.

사실 내가 Recoil을 도입하려던 목적이 로컬스토리지를 사용하지 않고 싶어서였다. 올해 1학기 수강했던 4학년 수업 '웹프로그래밍'에서 자바스크립트 관련해서 배운게 꼴랑 '로컬스토리지 저장하는 방법'이었기 때문에, 안좋은 수업 퀄리티로 인한 낙인이 찍혀 그 수업에서 다뤘던 것들은 왠만하면 사용하기 싫다는 고집이 생겼었다. 근데 로컬스토리지가 나쁜 것만은 아니다. 로그인 기능 구현 관련해서 서버에서 받아온 토큰을 저장해놓을 수단이 또 세션스토리지만한 것이 없기 때문이다.

상태 관리 라이브러리 중에 가장 유명한 Redux가 있었는데, 아예 사용할 줄도 몰랐고 초기 세팅 방법이 Context api 사용법과 굉장히 유사했기 때문에 기피하기도 했다. 하지만 이것도 나의 편견이자 잘못이었지. 쉬운 길로만 가려하면 반드시 탈이 나기 마련이다. Recoil은 처음 보는 나도 단번에 사용할 수 있을만큼 간결했지만, 껍데기만 그럴 뿐 다수의 상태를 관리해 본 경험이 전무했기 때문에 100% 기능을 활용할 수 없었던 것은 당연한 일이었다. 리팩토링을 하면서 Context api부터 다시 내 걸로 만들 필요가 있다.

결론

우선 잘 사용하지 못하는 Recoil 라이브러리를 다시 제거하고, Context API를 활용해 관리하는 방향으로 리팩토링할 것이다. 그리고 내가 깜빡한 것들 중 하나가 어플리케이션의 머리-가슴-배 느낌인 헤더와 푸터같은 요소들을 구분해놓지 않은 것인데 이도 마저 분리해놓을 예정이다.


내 코드와 동료들의 좋은 코드들을 나란히 펼쳐보니 경험의 차이에서 오는 부족함을 관찰할 수 있었다. 더 좋은 코드를 짜려면 좋은 코드들을 많이 보고 내 것으로 흡수하는 시간이 필요하다. 그 과정에서 지름길이란 있을 수 없다. 아무리 좋은 동료와 친구를 두고 그들에게 좋은 말들을 들어도 내가 직접 그것들의 필요성을 피부로 느끼기 전까진 내 것이 아니다.

0개의 댓글