[TIL] Next.js 세팅 + TypeScript

대빵·2023년 12월 26일
5

Next.js란?

React.js를 기반으로 만들어진 프레임워크(우리가 코드짤때 틀이 정해져있어서 그 틀에 맞춰서 사용하는것)이다.

라이브러리란?

특정한 문제를 해결하기 위한 툴

프레임워크란?

큰 단위의 솔리션을 위한 골격을 제공해준다. 여기에는 특정한 문제를 해결하는 툴도 포함되어 있다.

next가 제시한 6가지 특징

  1. 복잡한 설정 없이 사용하기 편하다
  • 복잡한 설정 대신 개발자로 하여금 쉽게 웹사이트 개발 할 수 있도록 한다.
  1. JavaScript만으로 프론트엔드, 백엔드 다 할 수 있다.

  2. 자동으로 코드스플리팅 해주고, 서버사이드렌더링이 가능하게 해준다.

코드스플리팅(Code Splitting)

코드 스플리팅은 웹 애플리케이션의 성능을 향상시키기 위한 기술 중 하나입니다. 대규모 웹 애플리케이션은 많은 양의 JavaScript 코드를 포함하고 있으며, 이는 초기 로딩 시간을 증가시키고 사용자 경험을 저하시킬 수 있습니다. 코드 스플리팅은 이러한 문제를 해결하기 위해 전체 애플리케이션 코드를 여러 부분으로 분할하고, 필요한 부분만 로딩하여 사용하는 기술입니다.

코드 스플리팅을 통해 애플리케이션은 초기 로딩 시간을 최소화할 수 있습니다. 사용자가 특정 기능이나 페이지로 이동할 때 해당 부분에 필요한 코드만 동적으로 로딩되기 때문입니다. 이는 더 작은 초기 번들 크기와 빠른 페이지 로딩을 가능케 하며, 사용자는 필요한 기능만 사용하는 동안 추가적인 자원을 다운로드하게 됩니다.

대표적인 코드 스플리팅 방법으로는 다음과 같은 것들이 있습니다:

  • 동적 임포트(Dynamic Import): JavaScript에서 제공하는 import() 함수를 사용하여 코드를 동적으로 로딩합니다. 이는 Promise를 반환하며, 모듈이 필요한 시점에 비동기적으로 로딩됩니다.
import('./module').then((module) => {
  // 모듈 사용
});
  • Webpack과 같은 번들러 사용: 번들러는 코드 스플리팅을 지원하고, 프로젝트를 여러 개의 작은 파일로 분리하여 필요한 부분만 로딩할 수 있도록 해줍니다.

코드 스플리팅은 특히 대규모 웹 애플리케이션에서 유용하며, 성능 최적화와 사용자 경험 개선에 기여할 수 있습니다.

서버사이드렌더링(Server-Side Rendering, SSR)

서버 사이드 렌더링은 웹 애플리케이션에서 페이지를 서버에서 렌더링하여 클라이언트에게 전송하는 기술입니다. 기존의 클라이언트 사이드 렌더링(Client-Side Rendering, CSR) 방식에서는 브라우저에서 JavaScript를 사용하여 동적으로 페이지를 생성하고 렌더링했지만, SSR은 서버에서 초기 렌더링을 수행합니다.

SSR의 주요 특징

초기 렌더링 속도 향상: 사용자가 웹 페이지에 접근할 때, 서버에서 HTML을 생성하여 클라이언트로 전송합니다. 이로써 초기 페이지 로딩 속도가 향상되고, 사용자는 빠르게 컨텐츠를 볼 수 있습니다.

검색 엔진 최적화(SEO): 검색 엔진은 HTML 컨텐츠를 크롤링하여 인덱싱하는데, CSR에서는 JavaScript를 실행해야만 페이지의 내용이 보이기 때문에 초기에는 검색 엔진에 제대로 노출되지 않을 수 있습니다. SSR을 사용하면 초기 렌더링 결과가 HTML 형태로 전달되기 때문에 검색 엔진이 콘텐츠를 쉽게 이해하고 인덱싱할 수 있습니다.

성능 최적화: SSR을 통해 서버에서 렌더링된 초기 마크업을 클라이언트로 전송하면 브라우저에서 페이지를 렌더링하는데 필요한 초기 부하가 감소합니다.

SSR을 구현하려면 프레임워크나 라이브러리에 따라 다양한 방식이 사용될 수 있습니다. 예를 들어, React에서는 Next.js와 같은 프레임워크를 사용하여 간단하게 SSR을 구현할 수 있습니다. Vue.js에서도 Nuxt.js와 같은 프레임워크를 사용하여 SSR을 구현할 수 있습니다.

SSR은 애플리케이션의 특성과 요구사항에 따라 선택되는 기술이며, CSR과 SSR을 혼합하여 사용하는 경우도 있습니다.

  1. 다양하게(언제, 어디서, 어떻게, 얼마나) data-fetching하게 해준다
  • data-fetching의 주기를 개발자의 입맛대로 정할 수 있다
  1. 요청사항을 예상 가능하게 한다

  2. 배포를 쉽게 할 수 있다

Next.js 설치

npx create-next-app@latest
yarn creat next-app 프로젝트이름


프로젝트를 생성하면 pages, public, styles폴더를 확인할 수 있다.

Next.js 공식문서

Next.js앱에는 index.html이 없는 이유

Next.js앱은 일반 React앱과 똑같이 public폴더를 가지고 있으며, 이 폴더는 정적인 파일을 저장하는데 사용된다. 하지만 일반 React앱과는 다르게 Next.js앱은 public폴더에 index.html파일이 없다.

Next.js는 서버 사이드 렌더링 기능을 제공하기 때문에, 서버에서 페이지를 렌더링하고, 이후 클라이언트에서 페이지를 JavaScript로 하이드레이션한다.
따라서 Next.js 앱은 public 폴더에 index.html 파일이 필요없는 것이다.

대신 pages 폴더 내부의 .js 파일을 통해 페이지를 정의하고,
필요한 정적 파일들은 public 폴더 내부에 저장하여 사용할 수 있다.

하이드레이션(Hydration)
: 서버 단에서 렌더링한 정적 페이지와 번들링된 JavaScript 파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 JavaScript 코드를 서로 매칭시키는 과정
Next.js의 Hydrate란?

yarn build실행

Next.js 프레임워크에서 프로덕션 환경으로 애플리케이션을 빌드하기 위한 작업이다.

Next.js는 React 기반의 서버 사이드 렌더링(SSR) 및 정적 사이트 생성(Static Site Generation, SSG)을 지원하는 프레임워크로, 개발자들이 쉽게 빠르고 효율적인 웹 애플리케이션을 구축할 수 있게 도와준다.

yarn build 명령을 실행하는 이유

  1. 번들링 및 트랜스파일링: Next.js는 자체적으로 웹팩(Webpack)을 기반으로 하는 빌드 시스템을 가지고 있다. yarn build 명령은 이 웹팩 빌드를 실행하여 프로젝트의 JavaScript 파일들을 번들로 묶고, 최적화된 형태로 변환한다. 이때, 최신 JavaScript 문법이나 다른 언어로 작성된 코드는 브라우저에서 이해할 수 있는 구버전의 JavaScript 코드로 트랜스파일링된다.

  2. 정적 페이지 생성: Next.js는 정적 사이트 생성(SSG)을 지원하여 빌드 시에 사전에 페이지를 생성할 수 있다. 이를 통해 초기 로딩 속도를 향상시키고 SEO를 개선할 수 있다. yarn build 명령은 이러한 정적 페이지 생성을 실행한다.

  3. 환경 변수 설정 및 기타 작업: 빌드 시에는 개발 환경과 프로덕션 환경에서 다르게 동작해야 하는 부분들을 설정하거나 처리하는 작업들이 포함될 수 있다. 예를 들어, 환경 변수를 설정하거나 필요한 환경에 맞게 설정 파일을 처리하는 등의 작업이 여기에 해당한다.

빌드 과정을 통해 생성된 결과물은 일반적으로 ./out 또는 ./build 디렉토리에 저장되며, 이 디렉토리의 내용을 서버에 배포하면 프로덕션 환경에서 Next.js 애플리케이션이 실행될 수 있다.

개발서버 열기

npm run dev
yarn dev

페이지 만들기

Next.js에서 URL과 페이지를 만드는 법은 매우 간단하다.
app폴더 안에 폴더 하나만 생성하면 폴더명과 동일한 URL이 자동으로 생성이 된다.
그리고 그 안에 page.tsx파일을 생성하고, 그 안에 코드를 작성하면 된다.

// src > app > page.tsx
export default function Home() {
  return null;
}
// src > app > layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "@/components/layout/Header";
import Footer from "@/components/layout/Footer";
import MainWrapper from "@/components/layout/MainWrapper";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Header />
        <MainWrapper>{children}</MainWrapper>
        <Footer />
      </body>
    </html>
  );
}
// src > app > about > page.tsx
import React from "react";

export default function About() {
  return <div>About</div>;
}
// src > components > layout > MainWrapper.tsx
import React, { ReactNode } from "react";

type MainWrapperProps = {
  children: ReactNode;
};

const MainWrapper = ({ children }: MainWrapperProps) => {
  return (
    <main className="bg-[#f4e8ee] px-4 py-4">
      <div
        className="flex justify-center bg-white
      mx-4 my-8"
      >
        {children}
      </div>
    </main>
  );
};

export default MainWrapper;

0개의 댓글