Next.js 기본 개념 및 사용법

이성훈·2021년 10월 18일
0

Next.js

Next.js란?

리액트의 SSR을 쉽게 구현할 수 있게 해주는 프레임워크입니다

심지어 코드 스플릿팅도 자동으로 쉽게 할 수 있습니다
코드 스플릿팅이랑 SPA에 단점인 보고싶은 페이지를 불러올때 모든 페이지에 대한 정보가 받아지는 것을 개선한 것으로 보고싶은 페이지에 대한 정보만 불러오게 유동적으로 해결해주는 방법입니다

Next.js에는 약간 정형화된 구조가 존재하는데요
SSR과 코드스플리팅을 위해 각 라우트에 해당하는 파일들을 소문자로 pages 디렉토리에 넣어야 합니다

추가적인 기능은 다음과 같습니다

  • 간단한 클라이언트 사이드 라우팅
  • Hot Module Replacement를 지원하는 Webpack 기반 작업환경
  • Express 나 그 어떤 Node.js 서버와 함께 사용 가능
  • Babel / Webpack 환경설정 커스터마이징 가능
  • 등등..

SSR의 장점

CSR의 단점을 해결해주는 SSR
1. CSR 경우 모든 js파일을 로드하기 때문에 사용자는 많은 시간을 대기해야 웹을 볼 수 있습니다
2. CSR 경우 자바스크립트가 로드되지 않은 경우 아무런 정보를 보여주지 않습니다. 결국 검색엔진에 잡히지 않는다는 단점이 있습니다

서버사이드렌더링은 위 두가지를 해결해주는 장점이 있습니다

설치

yarn add react react-dom next

// 타입스크립트
yarn create next-app --typescript
// sass
npm i sass

추가적으로 dev, build, start, lint와 같은 명령어가 있습니다

그리고 package.json에 다음과 같은 스크립트를 넣어줍니다

{
  "name": "hello-next",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "dev": "next"
  },
  "dependencies": {
    "next": "^2.1.0",
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  }
}

이제 아래 명령어를 통해 개발 서버를 실행할 수 있습니다

yarn run dev

라우팅

pages 폴더에 만들어진 파일은 라우트 경로가 됩니다.

Next.js에선 React와 다르게 Link컴포넌트에서 to 대신 href를 사용합니다.
또한 컴포넌트 내부에 문자열이 아닌 컴포넌트 or 엘리먼트가 있어야합니다.
스타일은 내부객체에다가 스타일링하시면 됩니다 엘리먼트를 사용하실 경우 onClick이벤트도 넣어주세요

<Link href="/main">
	<a>랄라</a>
</Link>

파일 구성

  • styled 폴더
    - global.css: _app.tsx에서만 사용
    - home.module.css: 다른 컴포넌트 등에서 import 해서 사용 (theme.js 역할?)

  • pages 폴더
    - index.tsx : 기본 페이지
    - _app.tsx
    - 모든 페이지 컴포넌트를 감싸고 있는 공통 레이아웃 (원하는 레이아웃을 컴포넌트를 import해서 추가하면 모든 페이지에 적용됨)
    - 가장 먼저 실행되며 페이지 업데이트 하기 전에 원하는 방식으로 페이지 업데이트 하는 통로
    - 내부의 컴포넌트들 전부 실행하고 html body로 구성
    - 이 이후 _document.tsx가 실행됨

  • _document.tsx
    - meta 태그 정의, 전체 페이지에 관여하는 컴포넌트
    - 따로 설정 안하면 디폴트값 적용
    - 이곳의 콘솔은 서버에서만 보이고 클라이언트에서는 안보임
    - componentDidMount 같은 훅도 실행이 안되며 static한 상황만 부여됨

    // pages/_document.tsx
    import Document, { Html, Head, Main, NextScript } from "next/document";
    export default class CustomDocument extends Document {
      render() {
        return (
          <Html>
            <Head>
              	// 모든페이지에 아래 메타테크가 head에 들어감  
				// 루트파일이기에 가능한 적은 코드만 넣어야 함! 
				// 전역 파일을 엉망으로 만들면 안된다 
				// 웹 타이틀 같은 것 넣음  
              <meta property="custom" content="123123" />
            </Head>
            <body>
              <Main />
            </body>
            <NextScript />
          </Html>
        );
      }
    }

사용법

component 폴더를 만들어 Layout.tsx를 만든 뒤 pages/_app.tsx를 Layout으로 감싼다

원하는 전역 스타일링이나 모든 페이지에서 나왔으면 하는 요소를 Layout.tsx 에서 제어.

Nav바 등등 모든 페이지에서 필요한 화면을 component 파일에 만든 뒤 Layout.tsx로 보낸다

→ 대충 _papp

pages 폴더 내부에서 원하는 페이지 루트를 만들고 필요한 컴포넌트들은 component 폴더 내부에서 만들어서 import한다.

내장 태그

  • SEO
    next/head
    import Head from 'next/head' 를 통해 넣어서 그 테그에 값을 넣으면 SEO가 잘 찾는 형태로 구현됨. → 안에 테그에 넣으면 웹 페이지 탭 이름이 그 이름으로 구현됨.

  • react-router-dom
    next/link
    import Link from 'next/link'

next/router
import { useRouter } from 'next/router'

Styled-component

  • 설치
// 기본 styled-components
yarn add styled-components @types/styled-components

// 문자열 안에 스타일 들어가는 것 처리를 위한 설치
yarn add -dev babel-plugin-styled-components

//전역 스타일링에서 이용하기 위함 
yarn add styled-reset 
  • 구조
    ├── styles
    │   ├── global-styles.ts      # reset 또는 공통적으로 사용하는 css
    │   ├── theme.ts              # 공통적으로 사용할 테마(media query, color 등 -> 필요할 때 ... )

global-styles.ts 예시

import reset from 'styled-reset'
    import { createGlobalStyle } from 'styled-components'

    const GlobalStyle = createGlobalStyle`
      ${reset}
      
      ...
      
 export default GlobalStyle

.babelrc 설정

 {
        "presets" : ["next/babel"],
        "plugins": [
            [
                "styled-components",
                {
                    "ssr": true,
                    "displayName": true,
                    "preprocess": false
                }
            ]
        ]
    }

_document.ts → 스타일 늦게 호출되는 현상 방지용

import Document, {
      Html,
      Head,
      Main,
      NextScript,
      DocumentContext,
    } from 'next/document'
    import { ServerStyleSheet } from 'styled-components'

    class MyDocument extends Document {
      static async getInitialProps(ctx: DocumentContext) {
        const sheet = new ServerStyleSheet()
        const originalRenderPage = ctx.renderPage
        try {
          ctx.renderPage = () =>
            originalRenderPage({
              enhanceApp: (App) => (props) =>
                sheet.collectStyles(<App {...props} />),
            })

          const initialProps = await Document.getInitialProps(ctx)
          return {
            ...initialProps,
            styles: (
              <>
                {initialProps.styles}
                {sheet.getStyleElement()}
              </>
            ),
          }
        } finally {
          sheet.seal()
        }
      }

      render() {
        return (
          <Html>
            <Head>
              <meta charSet="utf-8" />
            </Head>
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        )
      }
    }

    export default MyDocument

참조

벨로퍼트
개발하는 돌멩이

profile
블로그 이전중입니다 => https://kusdsuna.tistory.com/

0개의 댓글