19.2 Dynamic Imports
유저가 실제 그 컴포넌트를 사용할 것이라고 판단 될 때만 불러오는 것.

import dynamic from "next/dynamic"
const Bs = dynamic(() => import("@components/bs"), { ssr: false });
//이런 식으로 Bs 불러서 사용하면 됨.

// 서버단에서 로딩하지 않게 설정 가능.
// 서버에서 로딩한다면 파일위에서 컴포넌트 불러오고 렌더링 해주면
// nextjs는 서버단에서 일반 HTML로 export 해줄거야.
// 그러나 몇몇 라이브러리는 서버단에서 로딩하는게 불가능함. 그래서 서버단에서 불러오면 에러가 생가겠지.
// 이게 위처럼 {ssr:false}가 필요한 상황임.

props는 원래 하던대로 넣으면 됨. typescript에서 complain하지만 상관없음.
<>
  <Bs hello={true} />
  <Input
    name="phone"
    label="Phone number"
    type="number"
    kind="phone"
    required
    register={register("phone")}
  />
</>

물론 모든 컴포넌트를 다 dynamic으로 하지는 마라. 그럼 로딩이 오히려 이상해지겠지.

19.3 Lazy-load Imports 
만약 Dynamic import가 너무 오래걸린다면? 
loader 컴포넌트를 줄 수 있다.
3초동안 컴포넌트를 불러오는 동안, 옵션을 줄 수 있다.
아래는 dynamic 함수 사용하는거고.

const Bs = dynamic(
   () =>
     new Promise((resolve) =>
       setTimeout(() => resolve(import("@components/bs")), 3000)
     ),
   { ssr: false, loading: () => <span>Loading a big component for you!</span> }
 );


아래는 React18 부터 도입된 suspense기능을 사용하기 위한 설정.
true로 해놓으면 됨. 그리고 컴포넌트를 엘리먼트 부분에서 컨트롤 하는거

const Bs = dynamic(
  () =>
    new Promise((resolve) =>
      setTimeout(() => resolve(import("@components/bs")), 3000)
    ),
  { ssr: false, suspense: true }
);
 <>
  <Suspense fallback={<span>Loading something big</span>}>
    <Bs />
  </Suspense>
  <Input
    name="phone"
    label="Phone number"
    type="number"
    kind="phone"
    required
    register={register("phone")}
  />
</>



미들웨어란?
Request ----> Server ----> 서버내 함수(handler = controler()) ----> DB

그런데 로그인이랑 인증 요청을 처리하려면
컨트롤러 전에 믿르웨어를 사용해야 함.
Request ----> Server ----> 1. log() ----> 2. auth() -----> 서버내 함수(handler = controller()) ----> DB

아래 두개가 미들웨어
1. log(): 요청사항을 log해주는 함수
2. auth(): 인증쿠키 처리해주는 함
여기서 틀린게 없으면 인증 미들웨어가 controller에게 요청사항을 전달해줌

중간에 있느 소프트웨어지
어떤 중간에?
처음 유저가 보낸 request와 종착지(controller) 중간에 있는 함수!!!

node.js에서 많이 사용함.
server 파일이 따로 있음.
이 파일안에 사용하고 싶은 미들웨어들을 정리해놓음

근데 next.js는 서버리스임. server파일 없다.
근데 미들웨어 사용 가능!!!

client/useUser hook 모든 페이지에 사용해야 하는데. 이런걸 미들웨어로 만들어야지

pages폴더
루트폴터 안에 미들웨어 함수 적으면 됨.(12.2.0부터 루트에) middleware라고 적음 됨.
코드를 어디에 적느냐에 따라 스코프 설정이 됨.
페이지 바꿀 때마다 동작하게 하고싶다? -> 루트폴더에 미들웨어 작성
또는 프로파일 폴더 안에서만 움직일 때 동작하게 하고싶다? 해당 폴더에 미들웨어 작성
https://nextjs.org/docs/messages/nested-middleware

import type { NextRequest, NextFetchEvent } from "next/server";

export function middleware(req: NextRequest, ev: NextFetchEvent) {
  if (req.nextUrl.pathname.startsWith("/about")) {
    // This logic is only applied to /about
  }

  if (req.nextUrl.pathname.startsWith("/dashboard")) {
    // This logic is only applied to /dashboard
  }
}

이제 그냥 루트에 있는 미들웨어 파일하나로 다 써야함. 경로로 구분 하면 됨.


middleware.ts라는 이름의 파일을 root에 만들어라.

middleware
1. API 핸들러에 요청 보낼 때도 실행 됨.
2. 페이지 이동할 

19.1 Responses and Redirections

import { NextFetchEvent, userAgent } from "next/server";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export function middleware(req: NextRequest, ev: NextFetchEvent) {
  const ua = userAgent(req);
  // console.log(ua);
  // if (ua?.isBot) {
  //   return new Response("Please don't be bot"); //no longer works
  // }
  if (!req.url.includes("/api")) {
    if (!req.url.includes("/enter") && !req.cookies.has("carrotsession")) {
      return NextResponse.redirect(new URL("/enter", req.url));
    }
    // if (req.nextUrl.pathname.startsWith("/chats")) {
    //   console.log("chats");
    // }
  }
  // req.geo?.country
  // hosting provider 에 따라 다름.
}

+ Recent posts