티스토리 뷰

서버 사이드 렌더링까지 지원하는 리액트 애플리케이션을 만드는 데 많은 노력이 필요하며, 리액트 팀에서도 권하지 않음

 

4.3.1 Next.js란?

Vercel에서 만든 풀스택 웹 애플리케이션을 구축하기 위한 리액트 기반 서버 사이드 렌더링 프레임워크

PHP의 대용품으로 사용하기 위해 만듦

 

4.3.2 Next.js 시작하기

create-next-app 기반

npx create-next-app@latest --ts

 

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
}

module.exports = nextConfig

주석: 자바스크립트 파일에 타입스크립트의 타입 도움을 받기 위해 추가된 코드

swcMinify: SWC(바벨 대안, 번들링과 컴파일을 더욱 빠르게 수행, Rust로 작성) 기반 코드 최소화 작업 수행 여부

 

pages/_app.tsx

애플리케이션 전체 페이지의 시작점, 애플리케이션 페이지 전체 초기화

- 에러 바운더리를 사용하여 애플리케이션 전역에서 발생하는 에러 처리

- reset.css 같은 전역 CSS 선언

- 모든 페이지에 공통으로 사용 또는 제공해야 하는 데이터 제공 등

 

pages/_document.tsx

애플리케이션의 HTML 초기화, 서버에서만 렌더링

- html, body에 DOM 속성을 추가하고 싶은 경우

- next/document에서 제공하는 Head는 _document.tsx에서만 사용할 수 있음, 내부에 title 태그 사용 못함

- next/head에서 제공하는 Head는 페이지에서 사용할 수 있으며 SEO에 필요한 정보나 title 등을 담을 수 있음

- getServerSideProps, getStaticProps 등 데이터 불러오기 함수를 사용할 수 없음

- CSS-in-JS 스타일을 서버에서 모아 HTML로 제공할 수 있음

 

pages/_error.tsx

서버 혹은 클라이언트에서 발생하는 에러를 처리할 목적으로 만들어짐

전역 에러 처리

개발 모드에서는 Next.js 개발자 에러 팝업이 나타나 확인할 수 없고

프로덕션으로 빌드하여 확인해야 함

 

pages/404.tsx

404 페이지 정의

 

pages/500.tsx

서버 발생 에러 핸들링

_error.tsx와 500.tsx가 모두 있다면 500.tsx가 우선 실행

 

pages/index.tsx

웹사이트의 루트

 

[ ]

어떠한 값이든 해당 주소로 오게 됨

이미 정의된 주소가 있다면 해당 주소가 우선 됨

ex. /pages/hello/[greeting].tsx, /pages/hello/world.tsx

 

[...props]

전개 연산자와 동일하게 동작

 

Link(next/link), router.push 로 이동하는 경우 클라이언트 라우팅/렌더링 방식으로 동작

SSR-최초 페이지 빠르게 제공, SPA-자연스러운 라우팅 두 장점을 모두 살리기 위해

 

getServerSideProps

있으면 서버 사이드 런타임 체크

없으면 서버 사이드 렌더링이 필요없는 정적인 페이지로 분류 됨(빌드 시점에 미리 만들어도 되는 페이지)

 

/pages/api/hello.ts

서버의 API를 정의하는 폴더

HTML을 요청하지 않고 단순 서버 요청

일반적인 프런트엔드 프로젝트를 만든다면 사용할 일이 거의 없음

 

- 서버에서 내려주는 데이터를 조합해 BFF 형태로 활용

- 완전한 풀스택 애플리케이션 구축

- CORS 우회

 

4.3.3 Data Fetching

pages 폴더에 있는 라우팅이 되는 파일에서만 사용할 수 있음

예약어로 함수를 만들어 export를 사용해 함수를 파일 외부로 내보내야 함

 

getStaticPaths, getStaticProps

두 함수는 반드시 함께 있어야 사용할 수 있음

빌드 시점에 미리 데이터를 불러온 다음 정적인 HTML 페이지를 만들 수 있음

ex. 블로그, 약관 등

 

/pages/post/[id]

getStaticPaths

해당 페이지에 접근 가능한 주소(id)를 정의하는 함수

빌드할 페이지가 너무 많은 경우 fallback 옵션으로 미리 빌드하지 않도록 할 수도 있음

- false

- true: 빌드 전까지 fallback 컴포넌트를 보여줌

- "blocking": 별도 로딩처리를 하지 않고 대기하다가 렌더링이 완료되면 해당 페이지 제공

getStaticProps 정의된 페이지로 요청이 왔을 때 제공할 props를 반환하는 함수

 

getServerSideProps

서버에서 실행되는 함수

(브라우저 객체 접근 불가, api 요청 시 프로토콜과 도메인을 제공해야 함-서버는 자신의 호스트를 유추할 수 없기 때문)

props를 반환하거나 리다이렉트 처리

<script id="__NEXT_DATA__">로 삽입됨

반환값은 JSON으로 직렬화할 수 있어야 함(props의 결과를 HTML에 정적으로 작성해서 내려주기 때문에)

 

getInitialProps

서버와 클라이언트 모두 실행 가능

루트 함수에 정적 메서드로 추가(Post.getInitialProps), props 객체가 아닌 일반 객체를 반환

- pathname: 현재 경로명 /post/[id]

- asPath: 브라우저에 표시되는 실제 경로 /post/1

- query: URL에 존재하는 쿼리. params도 포함. query에 같은 값이 있다면 query가 우선됨

- req/res: Node.js에서 제공하는 HTTP request/response 객체

 

사용하기 까다롭고 주의할 점이 있기 때문에 getStaticProps나 getServerProps를 사용하고

getInitiaProps는 _app.tsx, _error.tsx 처럼 사용이 제한되어 있는 페이지에서 사용

 

4.3.4 스타일 적용하기

전역 스타일

_app.tsx에 import

 

컴포넌트 레벨 CSS

[name].module.css 명명 규칙 준수

 

SCSS와 SASS

scss에서 제공하는 variable을 컴포넌트에서 사용하고 싶다면 export 문법을 사용

 

CSS-in-JS

_document.tsx에서 getInitialProps를 사용하여 스타일을 모아주는 작업 필요(초기화)

swc를 사용한다면 nextConfig에서 compiler: {styledComponents: true} 추가 필요

 

4.3.5 _app.tsx 응용하기

MyApp.getInitialProps = async (context.AppContext) => {
  const appProps = await App.getInitialProps(context)
  const {
    ctx: { req },
    router: { pathname },
  } = context
  
  if (
    req && // 서버로 오는 요청
    !req.url?startsWith('/_next') && // 클라이언트 렌더링으로 발생한 getServerSideProps 요청이 아님
    !['/500', '/404', '/_error'].includes(pathname)
  ) {
    doSomethingOnlyOnce()
  }
  
  return appProps
}

조건을 모두 만족한다면 사용자가 웹페이지에 최초로 접근해서 최초 서버 사이드 렌더링을 수행했다고 볼 수 있음

userAgent 확인이나 사용자 정보 같은 애플리케이션 전역에서 사용해야 하는 정보를 호출하는 작업을 수행

 

4.3.6 next.config.js

basePath: 애플리케이션 시작점

swcMinify: swc 사용할 지 여부

poweredByHeader: X-Powered-By 헤더 사용 여부(보안 취약점)

reactStrictMode: 엄격 모드

assetPrefix: next에서 빌드된 결과물을 동일한 호스트가 아닌 다른 CDN 등에 업로드하고자 할 때 해당 CDN 주소 명시

(정적 리소스를 별도 CDN에 업로드하고 싶을 때 사용)

댓글
공지사항