교육 (Today I Learned)/Hanaro

[Hanaro] 35일차 / Next.js (Styling, Server API와 NextAuth, React+Next의 테스트 작성)

Bay Im 2024. 3. 8. 00:14

10 Next.js - Styling (TailwindCSS & Shadcn)

  • shadcn/ui 설치
    • cmd 창 next 프로젝트 최상단 디렉터리에서 npx shadcn-ui@latest init 입력
      • style: Default 선택
      • color: Slate 선택
      • CSS variables: yes 선택
  • shadcn/ui 사용
    • shadcn/ui는 필요한 컴포넌트를 바로바로 install 하여 사용할 수 있다.
    • https://ui.shadcn.com/docs/components/accordion 에서 필요한 컴포넌트 검색 후 install 하기
    • 예시
      • 버튼 사용하기
        • npx shadcn-ui@latest add button 입력
        • 자동으로 button.tsx 생성 완료

 

11 Next.js - Server API와 NextAuth 소셜 로그인

  • Server API 만들기
    • NextRequest와 NextResponse 사용
    • 예시
    • import { NextRequest, NextResponse } from 'next/server';
      
      export async function GET(req: NextRequest) {
        const { pathname, searchParams, host } = req.nextUrl;
        return NextResponse.json({
          id: 1,
          name: 'Hong',
          pathname,
          str: searchParams.get('str'),
          ip: req.ip || host,
          // cookies: req.cookies.getAll(),
        });
      }
  •  middleware
    • app 폴더 속이 아닌 app과 동일한 위치 폴더에 middleware.ts 생성
      • ex. src/middleware.ts
    • middleware 함수와 config를 export 한다.
    • matcher에 해당되는 path일 경우에만 middleware 작동
    • 예시
      • middleware.ts
      import { NextResponse } from 'next/server';
      import type { NextRequest } from 'next/server';
      
      export function middleware(request: NextRequest) {
        console.log('&&&>>', request.cookies);
        const didLogin = request.cookies.has('nextjs');
        if (!didLogin) return NextResponse.redirect(new URL('/photos', request.url));
        return NextResponse.next();
      }
      export const config = {
        matcher: ['/aaa', '/bbb/:path*'],
      };
  • next-auth 설치
  • next-auth 사용
    • cmd 창 프로젝트 최상단 디렉터리 위치에서 openssl 입력 (openssl 미설치 시 아래 확인!)
    • rand -base64 32 입력
    • 입력 후 나오는 결과가 .env.local 의 AUTH_SECRET

    • .env.local 파일 생성 후 openssl에서 발급한 AUTH_SECRET 결과 넣어주기
      • .env.local 예시
      AUTH_SECRET=openssl에서 발급한 auth_secret 값 넣어주기
      GOOGLE_CLIENT_ID=구글ID
      GOOGLE_CLIENT_SECRET=구글SECRET
      
    • Provider 생성
      • GoogleProvider 예시
      import GoogleProvider from 'next-auth/providers/google';
      
      export const {
        handlers: { GET, POST },
        auth,
      } = NextAuth({
        providers: [
          GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID as string,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
          }),
        ],
        secret: process.env.AUTH_SECRET as string,
      });
      
    • route.ts 생성
export { GET, POST } from '@/app/_lib/auth';
export const runtime = 'edge';
  • 윈도우에서 openssl 설치
    • 시스템 변수- 변수 중 Path 클릭 후 편집 클릭
    • 새로 만들기 클릭 후 C:\Program Files\OpenSSL-Win64\bin 추가
    • cmd 창에서 openssl 입력, version 입력 시 설치와 버전 확인 가능

 

12 Next.js - 그 밖의 기능들

  • Error Page
    • app/error.tsx 생성
    • error page는 client에서만 랜더링 된다.
    • 예시
    • 'use client';
      
      import { useEffect } from 'react';
      
      export default function Error({ error, reset,}: {
        error: Error & { digest?: string };
        reset: () => void;
      }) {
        useEffect(() => {
        }, [error]);
      
        return (
          <div>
            <h2>Something went wrong!</h2>
            <pre style={{ color: 'red' }}>{error.stack || error.message}</pre>
            <button onClick={() => reset()}>
              Try again
            </button>
          </div>
        );
      }
  • Loading Page
    • app/todos/loading.tsx 생성하면 자식 페이지(todos/[todoId]/page.tsx)도 함께 적용된다.
    • 예시
    • export default function Loading() {
        return <h1>Loading Todos...</h1>;
      }
  • Not Found(404) Page
    • app/not-found.tsx 생성
    • not-found 페이지를 만들지 않으면 next.js default 페이지 자동 생성
    • 예시
      • app/not-found.tsx
      export default function NotFoundPage() {
        return <h1>404: Not Found Page</h1>;
      }
      
      • app/todos/[todoId]/page.tsx
      import { notFound } from 'next/navigation';
      
      export default async function TodoPage({ params: { todoId } }: Params) {
        const todo: Todo = await getTodo(todoId); // {}
        if (!todo.id) return notFound();
      }
      
  • dynamic metadata
    • 예시
    • export async function generateMetadata({ params: { todoId } }: Params): Promise<Metadata> {
        const todo: Todo = await getTodo(todoId);
        return {
          title: todo.title,
        };
      }
  • .env 지원
    • default support dotenv
      • .env.local (또는 .env.development.local)
      • .env.development
      • .env
    • next.config.js
      • process.env.customKey 로 사용 가능
      module.exports = {
        env: {
          customKey: 'my-value',
        },
      }
      
    • 민감한 정보는 키 값 그대로 commit & push 하지 말 것
  • remove console
    • next.config.js 생성
      • 형식
        • removeConsole: true | {exclude: […]}
      • 예시
      const nextConfig = {
        compiler: {
          removeConsole: {
            exclude: ['error', 'debug'],
          },
        },
      };
      
    • build시 소스 코드의 console.log 자동 제거 해준다.
  • Using TurboPack 사용
    • package.json 수정
    • "scripts": {
        "dev": "next dev --port 3001",
        "dev:turbo": "next dev --turbo",
        "build": "next build",
      }
 

 

13 React와 Next의 테스트 작성(Jest & Test-Library)

  • Test in Next.js
    • cmd 창 프로젝트 최상단 디렉터리 위치에서 npm i -D @testing-library/jest-dom@5.16.5 @testing-library/react @testing-library/user-event jest jest-environment-jsdom ts-jest ts-node 입력
    • package.json scripts 블록에 아래 코드 추가
    • "test": "jest",
      "test:watch": "jest --watchAll"
    • cmd 창 프로젝트 최상단 디렉터리 위치에서 npm init jest@latest 입력
    • jest.config.ts에 아래 코드 추가
    • // setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
        moduleNameMapper: {
          '@/app/(.*)$': '<rootDir>/app/$1',
          '@/lib/(.*)$': '<rootDir>/lib/$1',
          '@/components/(.*)$': '<rootDir>/components/$1',
        },
     
  • Test 작성
    • tsconfig.json 파일을 복사, 붙여넣기 하여 tsconfig.spec.json 으로 이름 변경
      • tsconfig.spec.json 파일에서 "jsx": "react-jsx", 으로 변경
    • jest.config.ts 파일에서 transform: 아래에 아래 코드 추가
    • transform: {
          '^.+\\.[tj]sx?$': [
            'ts-jest',
            {
              tsconfig: '<rootDir>/tsconfig.spec.json',
            },
          ],
        },
    • 프로젝트 최상단 디렉터리에 test 폴더 생성
      • Home.test.tsx 파일 생성
      • About.test.tsx 파일 생성

 

14 배포 및 검색엔진 최적화

  • Vercel에 배포하기
    • Vercel 회원가입
    • 계정 연동
    • github application 설치
    • git repository import
    • Deploy