TWOSPOON 프로젝트 리뷰

나는 이걸 왜 하는가?

  • Hanspoon 프로젝트를 개선하고, 리팩토링 & 버전 업그레이드하고 싶어서
  • 새로운 기술과 마이그레이션을 경험해보고 싶어서

기획의도

  • 소소한 버그들과 유저의 불편함을 개선하는 과정을 경험해보자.
  • 공유 기능을 위해 상세 레시피 페이지를 따로 만들고, NextJS를 통해 멀티페이지 어플리케이션으로 만들자.
  • 새로운 기술스택으로 마이그레이션을 해보자.기술스택 변경

HANSPOON WEBSITE의 문제점 분석

레시피 공유에 적절하지 않은 상세페이지 렌더링 로직

  • 한스푼에서는 레시피 상세 정보를 팝업창으로 확인
    • 그러면 해당 페이지를 공유하는 경우 url로 들어갔을 때 팝업창 외의 뒷 배경의 모든 정보들도 함께 렌더링된 이후 팝업이 뜨도록 처리하거나
    • 별도의 상세 페이지로 접속하도록 이중으로 만들어 두어야 한다.
  • 그냥 별도의 페이지로 라우팅하기로 결정
    • 팝업(다이얼로그) 창에서는 검은색 배경이었지만 하얀색으로 색깔 반전을 주고 일반적인 페이지로 만들자.
  • SEO도 같이 챙기게 NextJS를 이용하여 Multipage application을 만들자.Hanspoon Header 컴포넌트 코드

유저 피드백에 의한 개선사항

  • 아코디언 컴포넌트에서 상세정보를 눌렀을 때 스크롤 튀는 문제
  • 페이지네이션 버튼 안에 아이콘이 일부 가려지는 문제
  • 공유와 북마크 버튼 사이의 간격이 너무 좁아서 어느 요소가 클릭되는지 불분명함

프로젝트 결과물

삽질의 과정

마이그레이션

겉모습만 똑같을 뿐 기술스택을 처음부터 끝까지 다 바꾸는 과정이 정말 쉽지 않았지만, 차이점을 확실히 알 수 있어서 재미있었다.

1. Styling (Sass module에서 styled-components로, 그리고 결국 emotion으로)

  • 성능 이슈가 거론되긴 하지만 우리의 프로젝트는 작고 소중한 사이즈이며 애니메이션이 많은 페이지도 아니기 때문에 CSS in JS도 나쁘지 않을 것이라는 판단
  • styled-components로 시작했다가 NextJS로 중간에 바꾸면서 NextJS가 emotion과 합이 잘 맞는다고 어디서 들어서 다시 emotion으로 변경 (어떤 부분에서 합이 잘 맞는지는 기억이 나지 않는다).
    • emotion과 styled-components의 차이점에 대해서는 이론적으로만 리서치했는데, css 프롭을 적극 활용하지는 않았던 터라 두 라이브러리 사이의 큰 차이는 느끼지 못했다.
    • styled components 코드와 emotion 코드가 다를 바 없어서 두 라이브러리 사이의 마이그레이션은 import 구문만 제외하면 할 게 없었음
  • 자바스크립트로 스타일링 코드를 작성할 수 있는 것은 신선한 경험이었고 좋았다.
    • 따옴표 속 css 코드에 syntax highlight가 안되는 탓에 자꾸 오타내서 머리박고 사죄하고 바로 vscode-styled-components 익스텐션 설치.
  • Before HanSpoon 스타일링: 컴포넌트에 상태에 따른 클래스이름을 준 후 sass 모듈파일에서 해당 클래스 이름에 스타일링을 적용Hanspoon Header 컴포넌트 코드 Hanspoon CSS 코드
  • After TwoSpoon 스타일링: 컴포넌트에 transient prop을 준 후 해당 프롭의 값에 따라 스타일링 문자열을 적용하도록 Styled component 작성Twospoon Header 컴포넌트 코드 Twospoon CSS 컴포넌트 코드

2. Routing (react-router-dom에서 NextJS가 다해주는 걸로)

  • NextJS를 쓰면서 프레임워크의 위대함을 느꼈는데, 대표적인 게 라우팅이었다.
    • 코드 작성할 필요도 없이 pages라는 폴더 안에 파일명만 잘 설정해두면 동적 라우팅까지 다 된다.
  • Before HanSpoon 라우팅 코드: useRoutes를 쓰거나 BrowserRouter 및 온갖 라우팅 컴포넌트를 덧씌웠어야 했던 과거는 안녕 Hanspoon 라우팅 코드
  • After TwoSpoon 디렉토리 및 파일: 넌 아직도 라우팅 코드로 하니? 난 파일명으로 해Twospoon 폴더구조

3. Prop Typing (prop-types에서 typescript로)

  • 타입스크립트는 프롭타입에만 해당하는 건 아니지만…
  • 마침 이펙티브 타입스크립트 책으로 함께 스터디 하면서 공부했던 걸 적용해볼 수 있었다.
  • 코드가 안정적이라 좋긴 한데 타입체크 통과하기 위해 인고의 타입에러 피하기를 거쳐야한다.
  • Before HanSpoon 프롭타입 정의: prop-types로 하나하나 정의해줬어야 했던 과거는 안녕Hanspoon 프롭 타입 정의 코드
  • After TwoSpoon typescript: 타입스크립트로 처리하면 되지롱Twospoon 타입스크립트 코드

4. 전역 상태 관리 (ContextAPI, constate에서, redux, RTK로)

  • 사실 리덕스로 관리할만한 다양한 상태가 없지만 그래도 리덕스 사용해보고 싶어서 오버엔지니어링을 어쩔 수 없이 선택
  • 향후 계속 업그레이드 하면서 TenSpoon 정도 되면 더 많은 복잡한 상태가 생길테니 미래지향적으로 생각해보자
  • redux 쓰려면 내가 일일히 다 작성하지 말고 RTK로 하는 게 좋을거라는 얘기가 무엇인지 알게 되었다.
  • Before HanSpoon constate: constate로 만든 훅으로 반환한 상태 및 상태변경 함수 사용 Hanspoon constate 코드
  • After TwoSpoon RTK Slice: 이것저것 넣고 slice만 만들면 useSelectoruseDispatch로 갖다쓰기Twospoon RTK slice 코드

5. Fetching & Caching (커스텀 훅에 직접 작성하던 fetch함수에서 RTK Query로)

  • Before HanSpoon useSearch 커스텀 훅: fetch 함수를 직접 작성했고, useRef를 활용하여 직접 캐싱 로직을 만들어 선택적으로 fetch 구현Hanspoon constate 코드
  • After TwoSpoon RTK Query: createApi로 fetch하는 url의 endpoint만 설정해두면 훅 이름까지도 다 자동생성해주며, 동일한 인자와 url로 가는 요청에 대해서는 store에 캐싱되어 있는 데이터를 반환Twospoon RTK slice 코드

스토리북

  • 스토리북은 직접 쓰기 전까지는 정말 어려워 보였는데 막상 해보면 그렇게까지 못할 건 아니었다.Twospoon Storybook Twospoon Storybook Twospoon Storybook
  • 장점: 컴포넌트별로 보면서 개발할 수 있어서 진정한 CDD가 가능하며, 이로 인한 굉장한 자존감 상승
  • 단점: 글로벌 스타일 등 전역에 넣어주어야 하는 설정들을 따로 해줘야 하는 약간의 번거로움, 그리고 너무 무거워서 스토리북 돌릴 때면 컴퓨터가 느려짐

기타 이슈

  • Sentry 마이그레이션도 NextJS를 위한 sentry 패키지를 깔고 환경설정만 몇개 하면 되는 거라서 충격적일 정도로 간편하다.
  • 내가 코로나 걸리는 바람에 재택 온라인 스크럼과 코드리뷰를 활발히 할 수 있었다. 오히려 좋아

발표 후 Q&A 및 피드백

  • 이미지가 늦게 뜨는데 그 이유가 무엇이라고 생각하는지
    • 원래도 해외에서 건너오는 이미지인데, 스토리북과 데브서버를 같이 돌리느라 느려져서 그렇다고 생각
    • 울군 선생님은 발표 전에 충분한 기도를 하고 올라갔어야한다고 조언해주심 (ㅋㅋ)
  • 스크롤 버그 문제는 어떻게 해결했는지
    • details, summary 내용이 양이 많아서 일어나는 문제라, 충분한 padding값을 주니 해결

느낀 점

  • 지금까지 했던 프로젝트 중 가장 배운 것도 많고 그만큼 재밌었던 프로젝트였다.
  • 취업을 위해 수많은 코딩테스트, 면접, 코로나 투병을 병행하면서도 끝까지 함께 한 팀원들 덕분에 더욱 좋았다.
  • 1년이 넘는 시간 동안 몸담았던 학원에서 하는 마지막 공식 프로젝트라서 더 감회가 새로웠다.
  • 앞으로 쓰리스푼 포스푼 텐스푼까지 해보는 것도 괜찮을 것 같다. (아마 팀원들이 싫어하겠지)