티스토리 뷰
서버 사이드 렌더링까지 지원하는 리액트 애플리케이션을 만드는 데 많은 노력이 필요하며, 리액트 팀에서도 권하지 않음
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에 업로드하고 싶을 때 사용)
'책' 카테고리의 다른 글
[리액트 딥다이브] 5 리액트와 상태 관리 라이브러리(2) (0) | 2025.04.21 |
---|---|
[리액트 딥다이브] 5 리액트와 상태 관리 라이브러리(1) (0) | 2025.04.13 |
[리액트 딥다이브] 4.1~4.2 서버 사이드 렌더링 (0) | 2025.03.25 |
[리액트 딥다이브] 3.1~3.2 리액트 훅, 사용자 정의 훅, 고차 컴포넌트 (0) | 2025.03.16 |
[리액트 딥다이브] 2.3~2.5 컴포넌트, 렌더링, 메모이제이션 (0) | 2025.03.09 |