Next.js + Typescript 초기세팅 하기

devstone·2021년 7월 16일
42

Next.js

목록 보기
1/2
post-thumbnail

🙈 Prologue

이번 솝트 28기 웹잼을 하며 처음으로 Next.js + Typescript 조합으로 프로젝트를 진행하게 되었습니다. 이번 웹잼을 위해 공부한 내용들을 공유하고자 합니다:D

0.React JS의 문제점

  1. 로딩중 화면일 때 검색엔진에 잘 안걸림. (SPA이기 때문)
  2. 한번에 모든 데이터를 가져오므로 비효율적 → 코드 스플리팅
  3. 서버사이드렌더링 두가지 종류
    • 프리렌더 : 검색엔진 알아차리고, 검색엔진일 때에만 백엔드 서버에서 데이터 가져와서 줌 , 일반 유저일 땐 기존 리액트 방식으로 줌
    • 서버사이드렌더링 : 첫 방문만 전통적인 방식대로 하고, 그 이후의 페이지 방문은 리액트 방식
  4. SSR 과 코드 스플리팅은 조금만 볼륨 커져도 효율성을 위해 적용해야 하는데.
    • 둘 다 필요 없는 경우) 어드민 페이지
    • B2C 서비스는 웬만하면 서버사이드렌더링 고려 필요

1. 초기 세팅

1-1. 설치 방법

  • 설치 with TS
    npx create-next-app --typescript
    # or
    yarn create next-app --typescript
  • Manual Setup
    npm install next react react-dom
    # or
    yarn add next react react-dom
  • 명령어들
    dev - Runs next dev which starts Next.js in development mode
    build - Runs next build which builds the application for production usage
    start - Runs next start which starts a Next.js production server
    lint - Runs next lint which sets up Next.js' built-in ESLint configuration

1-2. yarn dev 충돌날 때 (이미 3000포트 사용 중일 때)

$ lsof -i tcp:3000
$ kill -9 (PID숫자)

1-3. Eslint + prettier 설정

  • CRA와는 달리 자동으로 적용이 안돼서 직접 해주어야 한다
yarn add -D eslint 
               prettier 
               eslint-plugin-prettier 
               eslint-config-prettier 
               eslint-plugin-import 
               eslint-plugin-react 
               eslint-plugin-react-hooks 
               @typescript-eslint/parser 
               @typescript-eslint/eslint-plugin
  • .eslintrc
    {
      "extends": ["react-app", "prettier/prettier"],
      "plugins": ["react-hooks", "simple-import-sort", "prettier"],
      "rules": {
        "prettier/prettier": "error",
        "react-hooks/rules-of-hooks": "error",
        "simple-import-sort/imports": "error",
        "simple-import-sort/exports": "error",
        "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0 }],
        "comma-dangle": ["error", "always-multiline"],
        "object-curly-spacing": ["error", "always"],
        "space-in-parens": ["error", "never"],
        "computed-property-spacing": ["error", "never"],
        "comma-spacing": ["error", { "before": false, "after": true }],
        "eol-last": ["error", "always"],
        "quotes": ["error", "single"],
        "no-tabs": "error",
        "semi": ["error", "never"],
        "import/no-anonymous-default-export": 0,
        "object-shorthand": "error",
        "padding-line-between-statements": [
          "error",
          { "blankLine": "always", "prev": "*", "next": "return" }
        ],
        "@typescript-eslint/no-redeclare": 0
      }
    }
  • .prettierrc.json
    {
      "printWidth": 80,
      "semi": true,
      "singleQuote": true,
      "trailingComma": "all",
      "tabWidth": 2,
      "bracketSpacing": true,
      "endOfLine": "auto",
      "useTabs": false
    }

2. 기본 폴더 구조에 대한 이해

2-1. Public 폴더 내부 요소들

  • 정적 폴더, 브라우저에 직접 엑세스 가능

2-2. styles 폴더

  • global.css ) _app.tsx에서만 사용 가능
  • home.module.css ) 다른 컴포넌트 등에서 import 해서 사용 (다양하게 생성 가능)

2-3. pages 폴더

  • index.tsx : 홈페이지. 기본 페이지. global.css를 가져옴
  • _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>
        );
      }
    }

2-4. 일반적인 사용방법

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

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

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

    → 대충 _papp

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

3. Next 내장 테그

3-1. SEO를 위한 테그들

🐰 next/head

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

3-2. react-router-dom의 기능을 하는 테그들

import Link from 'next/link'

🐰 next/router

import { useRouter } from 'next/router'

4. Styled-component 사용하기

사용하려면 추가적으로 초기 세팅이 필요하다!

4-1. 설치

// 기본 styled-components
yarn add styled-components @types/styled-components

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

//전역 스타일링에서 이용하기 위함 
yarn add styled-reset 

4-2. 초기세팅

  • style 구조
    ├── 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}
      * {
        box-sizing: border-box;
      }
      body{
        font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
      }
      a {
        color: inherit;
        text-decoration: none;
      }
      input, button {
        background-color: transparent;
        border: none;
        outline: none;
      }
      h1, h2, h3, h4, h5, h6{
        font-family:'Maven Pro', sans-serif;
      }

      @media only screen and (max-width: 768px) {
        body {
          font-size: 12px;
        }
      }

      @media only screen and (max-width: 576px) {
        body {
          font-size: 10px;
        }
      }
    `

    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

번외) 환경변수 설정 에러 해결법

  1. 일단 Next.js 버전이 9.4 넘으므로 아래와 같은 방법 이용
    -> 공식문서
  • .env.local 에 설정한 이름대로 (NEXT_PUBLIC) 포함해서 접근할 것
  • 파일 이름 .env.local 한 번 수정해볼 것

🙉 Reference

https://www.cookieparking.com/share/U2FsdGVkX1-3k09RWDndD9HjAOWBHwwFM-eyMvjQZs7JJptDAY4R6fPfKcTRO0nQoqAeb4YgFPPlTtc5SEwHmbeBC92SPDghkQ9-_4yGLd8

profile
개발하는 돌멩이

3개의 댓글

comment-user-thumbnail
2021년 7월 20일

깔끔하게 정리해주셔서 잘 봤습니다! 감사합니다

1개의 답글
comment-user-thumbnail
2021년 7월 24일

사내 랜딩페이지 개발때문에 고민하던 도중 너무 좋은 자료를 찾았네요 :) 도움 많이 됐습니다, 감사합니다!

답글 달기