정적 생성 (Static Generation)

정적 생성 (Static Generation)

0. 시작하기 전..

 - 코딩앙마님의 강의를 참고하였습니다! (강의영상 바로가기)

 

1. 정적 생성

 - 저번 시간에는 서버사이드 렌더링으로 작업을 해보았으니, 이번엔 정적 생성으로 페이지를 작업해보겠습니다.

    ※ 정적 생성이란? (바로가기

 - #1. index.js 에서 다음과 같이 입력해줍니다.

import Axios from "axios";
import Head from "next/head";
import { useEffect, useState } from "react";
import ItemList from "@/src/component/ItemList";
import styles from "@/styles/Home.module.css";
import { Divider, Header, Loader } from "semantic-ui-react";

export default function Home({ list }) {
  return (
    <div>
      <Head>
        <title>NewBean</title>
        <meta name="description" content="NewBean 홈입니다."></meta>
      </Head>
      <>
        <Header as="h3" style={{ paddingTop: 40 }}>
          베스트 상품
        </Header>
        <Divider />
        <ItemList list={list.slice(0, 9)} />
        <Header as="h3" style={{ paddingTop: 40 }}>
          신상품
        </Header>
        <Divider />
        <ItemList list={list.slice(9)} />
      </>
    </div>
  );
}

// 정적 생성을 위한 코드
export async function getStaticProps() {
  const apiUrl = process.env.apiUrl;
  const res = await Axios.get(apiUrl);
  const data = res.data;

  return {
    props: {
      list: data,
      name: process.env.name,
    },
  };
}

 

- #2. .env.development.env.production에 들어가 다음과 같이 입력하여 추가해줍니다.

    - .env.development

apiUrl=http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline

 

    - .env.production

apiUrl=http://makeup-api.herokuapp.com/api/v1/products.json?brand=covergirl

 

 - #3. 실행해보면 다음과 같이 로딩화면 없이 바로 출력되는 것을 확인할 수 있습니다.

    → 메인 화면이 나오고 리스트가 생성되는 것이 아닌, 미리 만들어진 html을 보여주는 것입니다.

 

 - #4. Dynamic Routes도 해봅시다. 하지만, 모든 리스트를 다 만들 수 없으며, id를 알수 없기 때문에, 3개만 만들어보겠습니다.

    → pages 폴더 안에 detail 폴더 생성 후, 원래 있던 [id].js를 복사 붙여넣기 하고 다음과 같이 수정해줍니다.

import Axios from "axios";
import Head from "next/head";
import Item from "../../src/component/Item";

const Post = ({ item, name }) => {
  return (
    <>
      {item && (
        <>
          <Head>
            <title>{item.name}</title>
            <meta name="description" content={item.description}></meta>
          </Head>
          {name} 환경 입니다.
          <Item item={item} />
        </>
      )}
    </>
  );
};

export default Post;

export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: "499" } },
      { params: { id: "486" } },
      { params: { id: "473" } },
    ],
    // 페이지 대응
    fallback: false,
  };
}

// 서브사이드 렌더링을 위한 코드
export async function getStaticProps(context) {
  const id = context.params.id;
  const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await Axios.get(apiUrl);
  const data = res.data;

  return {
    props: {
      item: data,
      name: process.env.name,
    },
  };
}

 

 - #5. 그 다음 ItemList.js에 들어가 Linkhrefas주소를 다음과 같이 수정해줍니다.

<Link href="/detail/[id]" as={`/detail/${item.id}`}>
</Link>

 

    → 그 후 npm run buildnpm run start를 입력한 후, .next 폴더에 들어가보면 다음과 같이 해당 id에 대한 html이 생성됨을 확인할 수 있습니다.

 

 - #5. 브라우저로 들어가보면, 해당 id의 상품은 상세 페이지가 있으나, 다른 상품은 오류가 발생되는 것을 확인할 수 있습니다.

    → 다른 상품은 html이 생성되어 있지 않기 때문입니다.

 

 - #6. 다른 상품도 출력되기 위해 fallback: true로 변경 후, 다시 실행해봅시다.

    → 그러면 다른 상품도 정상적으로 출력됩니다.

    → 상세 페이지에 최초 접속 시, 백그라운드에서 정적 파일로 html을 생성한 후, Next.js가 프리 렌더링 목록에 추가합니다.

    → 두 번째 접속 시, 이미 만들어진 정적 생성 페이지를 사용하여, 상품의 상세 페이지가 바로 나타나게 됩니다.

    → fallback을 사용하면, 최초 접속자는 잠시 빈 화면을 보게 되겠지만, 이후 접속자는 정적 파일로 빠르게 제공받을 수 있습니다.

 

3. 정리하며

 - 정적 생성으로 작업하게 되면, 이미 생성된 html로 인해 JavaScript가 꺼있더라도 페이지는 정상 작동하게 됩니다.

 - Next.js에서 Linkprefetch라는 속성이 있는데, 이 것은 첫 번째 화면 or 스크롤을 했을 때, 뷰포트 내부에 있는 링크들은 다 프리로드 됩니다.

    → 프리 로드가 이루어 지면, 정적 생성이 되는 것입니다.

 - 지금까지 정적 생성에 대해 알아보았습니다.

 

※ 참고 깃 주소 : https://github.com/NewBean0312/nextjs-study/commit/954e43d20bc6afa4f82bc1744f0592e90168c6c5

 

정적 생성 · NewBean0312/nextjs-study@954e43d

NewBean0312 committed Dec 18, 2023

github.com

 

'Front-End Study > Next.js' 카테고리의 다른 글

API Routes  (0) 2023.12.22
isFallback, getStaticPaths  (0) 2023.12.20
에러 페이지와 환경 변수  (0) 2023.12.13
서버사이드 렌더링  (0) 2023.12.12
Dynamic Routes  (0) 2023.12.11