PJH's Shopping Mall - Start & Setting

박정호·2022년 12월 19일

Shopping Project

목록 보기
1/11
post-thumbnail

🚀 Start

이번엔 지금까지 활용한 것들과 다른 도구들을 사용해보려한다.

  • SWR 대신 React-Query를 통해 데이터 패칭하자.

  • Redux, Context API 대신 Recoil을 통해 상태관리해보자.

  • REST API 대신 GraphQL을 활용하여 API와 상호작용해보자.

  • Node, Express 대신 Apollo Server, Firebase를 사용해보자.

  • Webpack 대신 Vite를 통해 개발경험을 향상시키자.

  • npm 대신 yarn을 통해 모듈을 관리해보자.

  • tailwindCSS 대신 SCSS을 통해 모듈을 관리해보자.

늘 궁금했고 꼭 사용해보려 했던 것들이라 새롭게 배우는 재미도 있을 것 같다. 그리고 예전에 쇼핑몰 프로젝트를 진행하였지만, 완전 개발초보시절의 프로젝트라 제대로 구현된 기능이 하나도 없었다.

따라서, 앞서 말한 것들을 활용하여 간단한 쇼핑몰 프로젝트를 만들어보려 한다!



React-Query


SWR과 React-Query는 다음과 같은 특징을 갖는다.

기존에는 리덕스를 통해서 Global State와 Server State를 전부 포함하는 방법으로 상태관리를 하였다. 따라서, 비동기 로직을 사용하기 위해 장황한 코드가 필요하고 redux-thunk, redux-saga와 같은 미들웨어를 사용해야한다.

따라서, 이 작업을 매우 간편하게 만들어주고 데이터 캐싱을 아주 쉽게 해결해주는 것이 SWRReact-Query이다. 이들은 전역 상태관리 라이브러리가 아니라 서버와 클라이언트 간의 비동기 작업을 쉽게 해주는 라이브러리다.

  • 선언적으로 프로그래밍 할 수 있음(장황하지 않은 코드)
  • 동일한 API 요청이 여러 번 호출될 경우 한 번만 실행
  • 데이터가 dirty 해진 경우 적절한 시점에 알아서 업데이트
  • Global State와 Server State의 관심사를 분리

비동기 로직을 사용하기 위해 장황한 코드가 필요한 Redux에 비해 SWR이나 React Query을 사용할 경우에는 어떤 데이터를 언제 fetch 하면 되는지 목표만 기술하기 때문에 선언적으로 프로그래밍 할 수 있고, 이를 통해 글을 읽어내려가듯이 자연스럽게 흐름을 파악할 수 있어 가독성이 좋다.


확실히해야할 것은...

Redux 는 상태 관리 라이브러리로써, Client State, Server State 모두 관여할 수 있다는 것이고, 반면 SWR, React-Query는 data fetching 라이브러리로써 Client State 관점과는 다른 이야기로, 상태 관리가 필요한 경우에는 Recoil을 도입하면 좋을 것 같다.


두 라이브러리 모두 경쟁적으로 다양한 장단점이 있다.

SWR의 목표는 경량 라이브러리를 유지하여 React 요청 처리의 캐싱 문제를 해결하기 위한 최소한의 API를 제공하는 것이다.

React-Query는 동일한 문제에 대해 완전한 기능을 갖춘 솔루션을 제공하기 위해 노력한다.

React는 클래스 기반 구성 요소의 복잡성을 줄이기 위해 기능적 구성 요소를 도입했기 때문에 이러한 종류의 단순성을 좋아하는 개발자는 SWR을 선호할 수 있다.

그리고 상세하고 강력한 API로 작업하고 데이터 캐싱을 위한 프레임워크와 같은 올인원 솔루션을 찾는 개발자는 React-Query를 선호할 수 있다.

React-QuerySWR의 차이점을 크게 찾아볼 수는 없다. 단,하지만 React Query는 점차 발전해 왔고, 나온지도 오래 되어 안정성도 뛰어나서 현재는 프론트엔드 개발자들의 높은 선호도뿐만 아니라 지원하는 기능들의 수준도 탁월하다는 평가를 받고 있는 것 같다.

💡 참고하자!
👉 카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유
👉 REACT QUERY VS SWR
👉 React Query를 사용하며
👉 React에서 서버 데이터를 최신으로 관리하기(React Query, SWR)
👉 React Query와 상태관리 :: 2월 우아한테크세미나



Recoil

앞서 말했듯 React-Query를 활용하여 서버 데이터와 클라이언트 데이터를 분리할 수 있기 때문에 전역적으로 관리해야하는 데이터는 매우 적을 것이다..

따라서, Recoil같은 간소한 상태관리 라이브러리를 함께 사용해보자. 정말 간단히 사용할 수 있는 것에는 Context Api도 있지만, 이는 컴포넌트 하위 컴포넌트들에도 불필요하게 리렌더링이 발생한다는 단점이 있다.

반면 Recoil은 내부적으로 ref을 통해 상태를 전달하여 리렌더링을 방지한다.

React-Query, Recoil 두개를 적절히 잘 사용하면 좋을 것 같다.!

💡 참고하자!
👉 Recoil + React-query 삽질기
👉 React-Query 도입을 위한 고민 (feat. Recoil)



GraphQL

지금까지 나는 ServerAPI를 사용해서 클라이언트와 서버의 통신을 구현했다. 그 중 REST를 사용했었는데, 이번엔 GraphQL을 사용해보려 한다.

GraphQL은 HTTP 요청 횟수를 줄일 수 있고, HTTP 응답 사이즈를 줄일 수 있다. 또한 프론트엔드롸 백엔드 개발자의 부담을 덜어주기도 한다.

REST가 가지는 한계를 극복하기 위해 개발된 GraphQL이라고 하지만, 완벽하게 대체할 수 없다. 따라서, 적합도에 따라서 잘 선택하여 사용하는 것이 좋다.

다만, 지금까지 REST을 사용하여 통신을 구현했으므로 이번에는 GrapQL을 활용해보자!

💡 참고하자!
👉GraphQL이란?
👉GraphQL 개념잡기
👉REST API vs GraphQL



Mocker Service Worker

이전에 프론트엔드 IT기사를 읽으며 꼭 사용해보아야겠다는 것이 있었는데, 그 것이 바로 MSW이다.

프론트엔드 개발자는 백엔드 API를 활용하기 때문에 백엔드의 해당 부분이 완성 전까지는 개발을 진행할 수 없다. 따라서, 촉박한 기간일 수록 개발 완성도를 높이는 것은 압박으로 다가오는 경우가 많을 것이다.


이를 해결하기 위해, API 모킹(mocking) 라이브러리를 사용해보자.

쉽게 말해, 마치 백앤드 API인 척하면서 프런트앤드의 요청에 가짜 데이터를 응답해주는 기능을 활용한다.
덕분에 프론트엔드에서 API 없이도 프론트엔드 개발자는 높은 완성도를 갖고 있는 수준에서 개발을 진행항 수 있다.

특히 기존 API 모킹 라이브러리와 달리 MSW의 가장 큰 강점은 모킹이 네트워크 단에서 일어나기 때문에 프런트앤드 코드를 실제 백앤드 API와 네트워크 통신하는 것과 크게 다르지 않게 작성할 수 있다는 것이다.

즉, 나중에 가짜 API를 실제 API로 대체하는 것이 쉽다는 뜻이며 그만큼 프런트앤드 프로젝트의 개발 생산성이 올라가는 것을 의미한다.

💡 참고하자!
👉MSW로 백앤드 API 모킹하기
👉Mocking으로 생산성까지 챙기는 FE 개발
👉Mocking으로 프론트엔드 DX을 높여보자!
👉Mock Service Worker



Vite

나는 지금까지 Webpack을 사용하여 번들링하였는데, JS를 통한 개발은 점점 증가하고 있고 대규모 프로젝트에서 수천개의 모듈을 담으며 성능 병목 현상이 일어나게 된다.

따라서, 이번엔 Go로 만든 번들러 라이브러리인 Vite를 사용해보자.

Vite는 라이브러리를 설치하자마자 미리 bundle을 만들어놓고, 소스코드는 필요한 것만 건드리기 때문에 빠른 성능을 보인다고 한다.

💡 참고하자!
👉 Vite 시작하기
👉 Vite란?



yarn

자바스크립트 패키지 매니저로 npm을 많이 사용했는데, 이번에는 yarn을 사용해보자!

yarn은 동시에 여러 패키지들을 설치할 수 있기 때문에 속도가 향상된다.

또한 yarn은 yarn.lock이나 package.json으로 부터 설치만 하며, yarn.lock은 모든 디바이스에 같은 패키지를 설치하는 것을 보장하기 때문에 보안성과 안잔성을 보장한다고 한다.
하지만, npm 역시 계속하여 개선되고 있기 때문에 둘의 차이는 크지 않다.

따라서, 이번에 yarn을 제대로 사용해보며 직접 장단점을 느껴보자.



⚙️ Setting


😮 Next js 처럼 라우팅하기

기본 설치

1. yarn create vite
2. yarn

Vite을 이용하여 React를 구현해 CSR방식으로 진행하려 한다.
대신 vite용 Next.js 스타일 파일 시스템 기반 라우팅 플러그인을 사용해볼 것이다.

설치 with yarn

yarn add vite-plugin-next-react-router

vite.config.js에 다음과 같은 코드 추가

import { reactRouterPlugin } from 'vite-plugin-next-react-router';

export default defineConfig({
  plugins: [
    //...
    reactRouterPlugin(),
  ],
});

app.tsx에 useRoutes 사용

import { useRoutes } from 'react-router-dom'
import { routes } from './routes'

const App = () => {
  const elem = useRoutes(routes)

  return (
     <div>{elem}</div>
  )
}

export default App

main.tsx에 BrowserRouter 적용

import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom';
import App from './app'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
      <BrowserRouter>
        <App/>
     </BrowserRouter>

  </React.StrictMode>
)

_layout.tsx(전체 레이아웃) 생성

  • Suspense
    • 이 기술을 사용하면 컴포넌트 렌더링을 어떤 작업이 끝날때까지 잠시 중단시키고 fallback 속성으로 다른 컴포넌트(ex. loading...)를 먼저 렌더링할 수 있다.(참고)
  • Outlet
    • 이 기술을 중첩 라우팅을 통해 상위 컴포넌트를 레이아웃화 할 수 있고 {children}을 사용하는 것과 같은 효과가 난다.
import React, { Suspense } from 'react'
import { Outlet } from 'react-router-dom'

const Layout: React.FC = () => {
  return (
    <div>
      <Suspense fallback={'loading...'}>
        <Outlet />
      </Suspense>
    </div>
  )
}

export default Layout

yarn dev 시 routes.tsx파일 자동생성

  • React.lazy
    • 이 기술을 사용하면 동적 가져오기를 사용하여 구성 요소 수준에서 React 애플리케이션을 쉽게 코드 분할 가능(참고)


import React from 'react';
import GlobalLayout from './pages/_layout'

const DynamicIndex = React.lazy(() => import('./pages/index'));
const DynamicProductsIndex = React.lazy(() => import('./pages/products/index'));
const DynamicProductsId = React.lazy(() => import('./pages/products/[id]'));


export const routes = [
  {
    path: '/',
    element: <GlobalLayout />,
    children: [
      { path: '/', element: <DynamicIndex />, index: true},
      { path: '/products', element: <DynamicProductsIndex />, index: true},
      { path: '/products/:id', element: <DynamicProductsId />, },
    ]
  }
]

export const pages = [
  { route: '/' },
  { route: '/products' },
  { route: '/products/:id' },
]

👍 이제 Next.js처럼 파일 시스템 기반 라우팅을 사용할 수 있다!

  • 인덱스 라우팅
src/pages/index.tsx -> ‘’, ‘/’
src/pages/user/index.tsx -> ‘/user’
  • 중첩 라우팅
src/pages/user/list.tsx -> ‘user/list’
  • 동적 라우팅
src/pages/user/[id].tsx -> ‘/user/12’, ‘user/34

💡 참고하자!
👉 리액트에서 폴더 구조대로 라우팅하기 (feat. Vite)
👉 vite-plugin-next-react-router



🎨 SCSS

지금까지 css module, styled component, tailwind CSS를 사용하여 디자인하였는데, 이번엔 SCSS를 사용해보려 한다!

설치

yarn add -D sass

폴더 및 파일 생성

  • 대략적으로 디자인이 필요한 파일들을 생성하고, index파일에 import하자!
// index.scss
@import "products";
@import "cart";
@import "payment";

SCSS 적용하기

// main.tsx
import './scss/index.scss'

💡 참고하자!
[SCSS] 💎 Sass(SCSS) 개념 소개 & 설치 세팅 💯 정리

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글