[42gg] Next.js를 선택한 이유

jabae·2022년 8월 8일
2

프로젝트

목록 보기
5/8
post-thumbnail

(🔖 06.02 적었던 메모를 바탕으로 정리해봅니다.)

이번 프로젝트에 Next.js를 사용하기로 했다.

🤔 처음엔 Next.js를 사용하는 것을 망설였다. 써 본 경험이 없기도 했고, 내가 프로젝트를 이끌어야한다는 생각에 그래도 한 번 사용했던 리액트를 쓰는 게 낫지 않을까? 했지만 알아볼수록 장점이 많아 그래도 이번 기회에 같이 배워보는 것도 좋을 것 같다는 생각이 들었다.

팀원들도 프로젝트는 처음이기에 왜, 굳이 Next.js를 써야 하는 지 설득해야 했다. 그 때문에 나는 리액트와 비교하여 장점을 찾아보게 되었다. 많은 장점들 중, 내가 결정적으로 Next.js를 선택한 이유는 다음과 같다.

✅ Automatic Routing

🔆 pages 폴더 아래에 파일이름으로 라우팅해줘 직관적이다.

리액트와 비교해보자면, 리액트를 사용했을 때에는 이렇게 라우트 경로를 만들어주었어야 했다. 새 페이지를 만들 때마다 추가해 주어야하는 것도 나름 번거로운 작업이었다. 또 지난 42byte 프로젝트 중 갑자기 라우터하는 방식이 바뀌어서 당황했던 기억이...

export default function App() {
	return (
    	<Router>
        	<Routes>
				<Route path='/' element={<Main />} />
				<Route path='/blindboard' element={<Blindboard />} />
				<Route path='/writing' element={<Writing />} />
				<Route path='/detail' element={<Detail />} />
				<Route path='/mypage' element={<Mypage />} />
				<Route path='/admin' element={<Admin />} />
			</Routes>
        </Router>
    );
}

반면에! Next.js는 page 폴더 아래 만들어진 파일이 라우트 경로가 되는 매직 - 💫 따로 코드를 작성해주지 않아도 된다! 아주 똑똑한 프레임워크다. 👍

- pages/index.tsx → /
- pages/blindboard.tsx → /blindboard
- pages/writing.tsx → /writing
- pages/detail.tsx → /detail
- pages/mypage.tsx → /mypage
- pages/admin.tsx → /admin

이 외에도, Next.js는 자체적으로 Dynamic route도 제공해 준다. 아래의 예시처럼 userName에 따라 동적으로 라우팅이 가능하다.

- pages/users/[userName].tsx 
	→ /users/jabae.tsx
	→ /users/jihyukim.tsx
	→ /users/sujpark.tsx
	→ /users/daekim.tsx
	→ /users/kipark.tsx
	...

✅ Hot Code Reloading

🔆 수정 사항만 반영! 새로고침하지 않아도 수정사항만 빠르게 반영된다!

❓ Hot Reloading
애플리케이션의 상태를 잃지 않고 변경된 코드 부분만 새로 고친다.

코드를 변경하면, 페이지가 새로고침 되지 않고 변경된 부분만 자동으로 즉시 적용된다. 새로고침이 되지 않기 때문에 데이터를 집어 넣고, 일부 부분만 수정하면 그 데이터는 새로고침 되지 않기 때문에 개발자는 빠르게 수정사항을 비교해볼 수 있다.

리액트에서 Hot Reloading을 하기 위해서는 React Hot Loader라는 라이브러리를 따로 설치해 줘야 한다고 한다.

✅ Code Splitting

🔆 로딩한 페이지가 꼭 필요로하는 파일만 로드해, 첫 화면 렌더링이 빠르다.

❓ Code-splitting
애플리케이션 번들을 각 진입점에 필요한 더 작은 청크로 분할하는 프로세스이다. 목표는 해당 페이지를 실행하는 데 필요한 코드만 로드하여 애플리케이션의 초기 로딩 속도를 개선하는 것이다.

웹사이트를 처음 들어가게 빈 html파일에 js가 실행되어 렌더링되어야 하는데, 리액트는 최초 렌더링시 모든 js파일을 가져와야 하기 때문에 시간에 많이 걸린다. 이에 비해 Nextjs는 꼭 필요한 파일만 로드하기 때문에 첫 화면 렌더링이 빠른 장점이 있다.

처음 페이지 진입시 로딩이 길면 사용자가 불편할 수 있는데, 첫 화면 렌더링 속도가 빠른 장점은 아주 큰 장점이라고 생각되었다.

✅ SSG & SSR

🔆 서버 사이드 렌더링이 가능하다!

❓SSG (Static-site Generation)
애플리케이션 빌드를 진행할 때, 각 페이지들에 대해 정적파일을 생성해 페이지를 미리 렌더링(pre-rendering)한다. 해당 페이지를 요청하면 미리 생성된 페이지를 반환해 재사용하므로 응답 속도가 빠르다.

❓SSR (Server-side Rendering)
클라이언트 사이드로 html을 보내기 전에 서버사이드에서 컴포넌트를 렌더링할 수 있다. 즉, 브라우저가 자바스크립트 파일을 해석하고 보여질때까지 기다리지 않고 바로 렌더링을 하기 때문에 사용자에게는 좋은 경험을 줄 수 있다.

Next.js 를 사용하면 각 페이지에 사용할 사전 렌더링 양식(Static-site Generation / Server-side Rendering / Client-side Rendering)을 선택할 수 있다.

SSG를 이용하려면 getStaticProps을 사용하면 된다. 주로 제품목록, 도움말 및 문서처럼 각 요청에 동일한 정보를 반환하는 경우에 사용한다.
SSR을 이용하려면 getServerSideProps을 사용하면 되는데, 모든 요청에 실행하므로 항상 최신 상태를 유지해야 하자주 업데이트 되는 데이터에 사용한다. 서버측 렌더링은 성능을 저하시킬 수 있다고 하니 어떤 데이터를 서버사이드에서 렌더링할 지 신중히 선택해야 한다고 공식 문서에 나와있다. 리액트에서도 SSR이 가능하지만

🤔 SSR 부분이 큰 장점 중 하나지만 아직 사용해보지는 않았는데, 공부가 좀 더 필요하다. 일단 출시일에 맞추기 위해 모든 페이지는 CSR로 만들었는데, 조금 더 공부해 본 후 어떤 데이터를 SSR로 요청할 지 판단하고 코드 수정이 필요하다.

✅ Prefetching

🔆 다음 페이지의 코드를 미리 가져와 페이지 전환이 즉각적이다.

Next.js에서 제공하는 next/link는 다음 페이지의 코드를 미리 가져와 빠르게 로드한다. 브라우저에 페이지를 로드할 때, Link가 나타나면 Next.js는 Link로 연결된 페이지의 리소스를 백그라운드에서 미리 패치해서 사용자 친화적으로 빠른 페이지 전환을 제공한다.

✅ TypeScript

🔆 typescript로 만들어져 TypeScript 친화적인 환경을 제공한다.

우리 프로젝트는 typescript를 사용하기로 했는데, 기본적으로 typescript 친화적으로 만들어졌다고 하니 쓰지 않을 이유가 없었다!!! 공식 문서에서도 typescript를 사용할 때의 이용방법이 상세히 나와있어서 너무 좋았다.😁

✅ (추가) API Routes

🔆 pages/api 폴더 아래의 파일로 REST API를 구현할 수 있다.

pages/api 폴더 아래의 파일은 페이지가 아닌 API 엔드포인트로 인식되기 때문에 REST API를 구현할 수 있다. 목업 데이터를 만들기 위해 굳이 다른 라이브러리를 사용하지 않아도 되므로 매우 편리했다. 또한 미들웨어, response, redirect도 가능하다.

사용법은 간단하다. 이렇게 pages/api 폴더 아래 파일을 만들면 api가 만들어지는 것이다.

- pages/api/pingpong/users/index.ts → /pingpong/users
- pages/api/pingpong/ranks/[type].ts → /pingpong/ranks/${1}
- pages/api/pingpong/match/tables/[tableId].ts → /pingpong/match/tables/${1}
...

pages/api 폴더 아래의 파일의 내용은 다음과 같다. 유저 데이터를 예시로 들면 아래와 같다.

import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<UserData>
) {
  const obj = {              // 응답할 데이터 
    userName: 'jabae',
    userImageUri: '/vercel.svg',
    myRank: 2,
    notiCount: 4,
    userState: { isPlaying: false, gameId: 3 },
  };
  res.status(200).json(obj); // 상태 코드와 데이터 응답
}

페이지나 컴포넌트에서 호출하면 데이터를 받아 사용할 수 있다.

import axios from "axios";

const getDataHandler = () => {
  axios.get('/api/users')
       .then((response) => console.log(response.data))
}

✅ 그 외

그 외에도 자체적으로 이미지 최적화도 지원해준다고 한다. 우리는 유저 이미지를 42에서 받아서 쓸 계획이었고, 게임 결과 리스트에 모든 유저의 이미지를 보여줘야 하므로 이 부분도 꽤 중요하다고 생각되었다. 그리고 라우터를 굳이 임포트하지 않아도 자체 next/router를 제공한다. 또 404 페이지도 커스텀할 수 있다고 하니... 뭐야 완전 똑똑이네 안 쓸 이유가 없었다. 😮


👊 후기

😊 이제 써 본 지 일주일 정도 되었는데 아주 만족스럽다! 코드 수정한 부분의 적용도 넘나 빠르고, 라우팅이 너무 편하다. 또 또 또 ! 위의 추가에 볼 수 있득 자체 api를 제공하는 게 너무 편했다. 백엔드단에서 테스트 서버를 만들어주기 전까지 42byte에서는 json-server 라이브러리를 이용해 목업 데이터를 만들었는데, NExt.js는 자체적으로 API Routes를 제공한다... 신세계... 기획 초반에 목업 데이터를 위해 msw를 사용하려고 했지만 그럴 필요도 없어졌다! 넘 조아! 😍

참고 📚

profile
it's me!:)

0개의 댓글