TIL33. next.js 맛보기

imloopy·2022년 6월 27일
0

Today I Learned

목록 보기
39/56
post-custom-banner

오늘 배운 것들

  • 서버 사이드 렌더링
  • nextjs
    • 초기 설정
  • getServerSideProps
  • api Routes

서버 사이드 렌더링

  • 서버에서 데이터까지 모두 포함하여 완전한 페이지를 구성한 뒤(서버에서 렌더링을 마친 뒤), 이를 사용자에게 보여주는 방식을 말한다.
  • 주소를 이동할 때마다 각 주소에 맞는 페이지를 불러와 브라우저에서 보여준다. (서버에서 렌더링을 한 뒤 브라우저에서는 템플릿만을 보여준다.)

왜 서버 사이드 렌더링을 해야 하는가?

  • 검색 엔진 최적화
    • 클라이언트 사이드 렌더링은 처음에 서버로부터 빈 템플릿을 불러오고, 나머지 부분을 자바스크립트를 실행하여 동적으로 실행한다. 따라서 검색 엔진 수집 봇들은 빈 템플릿만을 수집하게 되며, 흔히 사용되는 meta태그들의 적용이 안 되는 문제가 있다.
  • 더 빠른 초기 로딩 속도
    • CSR 서버로부터 실행할 자바스크립트 파일을 받은 뒤 동적으로 실행하기 때문에 첫 화면이 띄워지기 까지 걸리는 시간이 SSR에 비하여 길다. 따라서 사용자들은 빈 화면을 보는 시간이 길어진다.
    • 반면에 SSR은 데이터 처리를 서버에서 진행하므로, 클라이언트는 템플릿을 보여주기만 하면 된다.

이전 node.js의 ejs 또는 java spring의 jsp 등이 SSR 방식이다. SSR 방식은 동적으로 페이지를 구성하기 어려워 CSR 방식이 주목받게 되었지만, 검색 엔진 최적화와 초기 로딩 시간 문제로 인하여 페이지의 일부를 프리 렌더링 하는 SSR on SPA 방식이 유행하게 되었다.

Nextjs

  • 기본적으로 서버 사이드 렌더링으로 동작하며, 처음 페이지를 불러올 때에는 서버사이드이지만, 다시 불러올 때에는 매우 빠른 속도로 불러올 수 있다.
  • head태그와 link, image 태그를 자체적으로 제공한다.
    • link 태그는 client side rendering으로 페이지를 이동하게 된다

api directory

  • api 디렉토리는 api/path 로 접근할 경우, data를 전달할 수 있는 api 서버 역할을 한다.
  • node.js의 문법과 비슷하지만, 이는 언제까지나 간이로 사용할 수 있다 뿐이지 많은 기능들을 넣으려면 자체 api 서버를 구축하는 것이 더 좋을 것 같다.

이슈

babel 관련 이슈

  • emotion 설치하는데 babelrc가 필요하고, babelrc를 사용하니까 터미널에서 경고 문구가 떴다.
  • nextjs는 자체적으로 바벨이 아닌 swc라는 트랜스파일러를 이용하는데, emotion은 이 swc 트랜스파일러를 지원하지 않는다.
  • babelrc를 설정하면 자동으로 swc가 아닌 babel환경으로 트랜스파일이 되는데, 이 때 속도저하가 발생한다.
  • emotion이 swc를 빨리 지원하는 수 말고는 답이 없당

느낀 점

  • 기본적으로 리액트 기반의 프레임워크이기 때문에 webpack 등 설정할 것이 많은 리액트에 비해서 기본적으로 webpack과 babel을 설정할 필요가 없었다.
  • 리액트는 기본으로 webpack config.js에 정의되어 있는 부분이 많아, 빌드 최적화를 위하여 웹팩으로 커스터마이징 하는 것이 국룰이었는데, next는 create-next-app --typescript 만으로도 충분했으며, 기본적으로 필요한 플러그인들 (env, scss 등등)은 모두 깔려있어서 그것은 너무 편했다. 또한, webpack.config.js 처럼 babel.config.js 세팅 파일을 통해 좀 더 필요한 플러그인이나 alias 등을 간단히 추가해 주는 것만으로 webpack을 정의한 것과 동일하게 동작하는 점이 맘에 들었다.
  • 페이지 라우팅은 리액트에서 사용하는 방식에 비해 훨씬 편하다. 단순히 pages에 폴더를 정의하면 그 폴더가 곧 path가 된다.
    • ex) 폴더 구조가 @pages/hello/index.tsx일 경우, 실제 주소창에 검색하는 주소는 https://localhost:8080/hello가 됨

    • 뒤에 동적 주소를 사용하고 싶다면 파일이름을 [id].tsx 형식으로 이름을 짓고, 컴포넌트 내부에서 다음과 같이 작성하면 된다.

      // @pages/posts/[id].tsx
      import { useRouter } from 'next/router';
      import React from 'react';
      import { Post as PostInterface } from '@/interfaces';
      import { NextPageContext } from 'next';
      import axios from 'axios';
      
      // getServerSideProps에서도 해당 id를 사용할 수 있다.
      export const getServerSideProps = async (ctx: NextPageContext) => {
        try {
          const postId = ctx.query.id;
          const { data: post } = await axios.get<PostInterface>(
            `https://someapi.com/posts/${postId}`,
          );
          return {
            props: { post },
          };
        } catch (error) {
          if (axios.isAxiosError(error) && error.response?.status === 404) {
            // ANCHOR: not found시 404page로 자동으로 이동한다.
            return {
              notFound: true,
            };
          }
        }
        return {
          props: {},
        };
      };
      
      const Post: React.FC<Props> = ({ post }) => {
        const router = useRouter(); // router.query.id로 접근
        return (
          <div>
            <h1>{post.title}</h1>
            <p>{post.body}</p>
          </div>
        );
      };
      
      export default Post;
  • 그러나 서버 사이드 렌더링을 최적화 하기 위해서는 좀 더 많은 기술들을 습득해야 할 필요가 있다. 실제로 CSR 과 SSR의 차이에 대해서 이론적으로나마 공부를 해 보았지, 실제로 서버 사이드 렌더링으로
  • getServerSideProps으로 pre-fetch 하는 방식이 신선했다. 어떻게 미리 불러오면서 이렇게 동적으로 페이지를 구성할 수 있는 것인지 (hydration) 실제로 보니까 더 신선하다. 그런데 이제 막 useEffect로 사이드 이펙트를 실행하는 리액트의 상태 관리에 겨우 익숙해졌는데, 새로운 것을 배우려니까 다소 생소한 부분이 있다.
  • next js 뽀개보자!!

출처

초보 웹 개발자를 위한 자바스크립트 빌드 툴과 SWC
swc-disabled | Next.js
PowerPoint 프레젠테이션 (deview.kr)

post-custom-banner

0개의 댓글