이전에 진행했던 쇼핑몰 프로젝트를 리팩터링 하고자 한다. 초기 프론트엔드 skill을 배운 지 얼마 되지 않았을 시점에 팀원들과 함께 구축한 프로젝트이기 때문에 다양한 라이브러리를 사용하지 못했다.
이번 게시글은 적절한 라이브러리 선택과 그 이유에 대해 정리하고자 한다.
TypeScript
JavaScript의 경우 동적 타입으로 런타임(동작 환경)에서 동작할 때 오류를 발견할 수 있으며, 이는 큰 문제로 이어질 가능성 있다.
TypeScript의 경우 코드를 작성할 때 타입을 정해서 작성하기 때문에 코드 작성 단계에서 타입에 대한 오류를 확인할 수 있다. 때문에 코드를 작성할 때 발생하는 오류를 JavaScript보다 줄일 수 있게 된다.
위의 간단한 이유만으로도 TypeScript의 사용 이유는 충분할 것이다.
Next
리액트로 개발할 때 SPA(Sing Page Application)을 이용하며 CSR(Client Side Rendering)을 하기 때문에 좋은 점도 있지만 검색 엔진 최적화(SEO) 부분의 단점도 존재한다.
CSR을 하면 첫 페이지에서 빈 HTML을 가져와서 JS파일을 해석하고 화면을 구성하기 때문에 포털 검색에 거의 노출될 일이 없다. 하지만 Next.js에서는 Pre-Rendering을 통해서 페이지를 미리 렌더링 하며 완성된 HTML을 가져오기 때문에 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달할 수 있게 된다.
SSR은 클라이언트(client) 대신 서버에서 페이지를 준비하는 원리이다. 앞서 언급한 대로 리액트에서는 CSR을 하기 때문에 서버에 영향을 미치지 않으며, 서버에서 클라이언트로 응답해서 보낸 html도 거의 비어있다.
이러한 CSR은 다음과 같은 문제를 가지고 있다.
- 서버에서 데이터를 가져올 때 지연 시간 발생으로 UX 측면에서 좋지 않을 수 있다.
- 검색 엔진에 검색 시 웹 크롤링이 동작할 때 제대로 가져와 읽을 수 없기 때문에 검색 엔진 최적화가 문제가 된다.
Next.js를 사용하면 위의 문제를 해결할 수 있다. Next.js는 SSR을 이용하여 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달할 수 있어 검색 엔진 최적화가 가능해진다.
쇼핑몰의 특성상 상품 검색 시 웹 크롤링이 동작할 때 상품 데이터를 사용자에게 노출해야 되기 때문에 검색 엔진 최적화가 필수라고 생각한다.
React-query
리팩토링 전 프로젝트는 전역 상태 관리를 전혀 하고 있지 않다. 로컬로 관리한 상태는 멀리 떨어져 있는 컴포넌트에서 필요한 경우 많은 불편함이 있었다. 이러한 이유로 리팩토링 프로젝트에는 전역 상태 관리를 Redux를 사용할 생각이었다. 또한 서버와의 API 통신과 비동기 데이터 관리에 Redux-thunk를 사용할 생각이었다.
서버와의 API 통신으로 얻은 비동기 데이터를 Redux를 이용하여 전역 상태로 관리할 생각이었지만, 다음과 같은 문제가 발생한다.
비동기 데이터를 컴포넌트(component)의 상태(state)에 보관하게 될 경우 다수의 컴포넌트의 Lifecycle에 따라 비동기 데이터가 관리되므로 캐싱 등 최적화를 수행하기 어렵다. 또한 다수의 컴포넌트에서 동일한 API를 호출하거나, 특정 API 응답이 다른 API에 영향을 미치는 경우 등 복잡하지만 빈번하게 요구되는 사용자 시나리오에 대응하기가 쉽지 않다.
또한 Redux는 API 통신 및 비동기 데이터를 관리하는 라이브러리가 아니기 때문에 데이터 관리를 위해 관련 코드를 모두 직접 작성해야 한다. 단지 데이터를 저장하는 로직뿐 아니라 loading, error 등을 추가로 관리해줘야 한다.
서버 통신을 통해 가져온 데이터를 Redux store에 저장하는 것은 redux가 추구하는 진실된 정보의 원천에 부합하는가에 대한 고민을 해보았다. store에 저장된 데이터는 서버에서 가져온 데이터 복사본에 불가하다. 클라이언트에 담긴 서버 데이터가 응답 객체에 담겨 서버를 떠나는 순간 해당 데이터는 최신 데이터라고 보기 어려운 것이다.
그리고 서버의 데이터가 바뀌지 않았는데 컴포넌트의 Lifecycle에 따라 다시 API 요청을 하고 데이터를 관리할 필요가 있을까? 서버의 데이터가 바뀌지 않았다면 API 요청을 보내는 것이 아닌 브라우저 캐시 등의 저장 공간을 활용할 수 있을 것이다.
애플리케이션에서 서버의 상태를 불러오고, 캐싱, 지속적인 동기화하고 업데이트하는 작업을 도와주는 react-query를 사용한다면 쉽고 자연스럽게 API 요청과 비동기 데이터 관리가 가능해지며 위의 문제와 의문은 해결될 것이다.
마지막으로 Next.js를 사용하는데 react-query 사용에 대한 의문이 들 수 있다. react-query를 추가로 사용하는 가장 큰 이유는 캐싱을 자동으로 해준다는 점이다.
Redux
앞서 react-query의 사용 이유를 정리했다. 추가로 Redux를 사용하여 UI 등 필요한 상태(state)를 관리할 예정이다.
React에서 제공하는 Context API를 사용할 수도 있겠지만, reducer의 상태의 불변성을 지키기 위해 작성할 장황한 코드를 생각하면 숨이 막힌다.
redux-tookit을 사용한다면 내부의 immer 라이브러리를 덕분에 불변성을 지키기 위한 코드 작성을 해주지 않아도 된다. 이것만으로도 redux 사용 이유는 충분하다 생각한다.
Emotion
리팩토링 전 프로젝트의 경우 프로젝트 기획 단계에서 class 명이 겹치는 것을 고려해 css module와 emotion 사용을 고민했었다. 결국 css module로 결정했다.
사전에 염두에 두었던 문제는 덕분에 발생하지 않았지만, 컴포넌트 파일이 많아질수록 그에 따라 css module 파일 또한 많아져 불편했으며, 가장 큰 문제는 동적으로 css를 처리하기 위한 코드 작성이 너무 많았다.
이러한 이유로 리팩토링 프로젝트는 css module이 아닌 emotion을 통해 CSS-in-JS 방식으로 상황에 따른 UI를 구현할 예정이다.
'Project' 카테고리의 다른 글
통합 쇼핑 플랫폼 - 12st 회원가입 본인인증, 사용자 입력 정보 저장(Feat. Firebase 적용기) (0) | 2023.05.11 |
---|---|
통합 쇼핑 플랫폼 - 12st Troubleshooting 🚀 (이벤트 버블링) (0) | 2023.03.22 |
[TEAM PROJECT] 통합 쇼핑 플랫폼 - 12st (0) | 2022.11.29 |