icon안동민 개발노트

일반적인 오류 및 해결 방법


 Next.js App Router를 사용한 개발 과정에서 발생할 수 있는 다양한 오류와 그 해결 방법을 살펴보겠습니다.

빌드 오류

 모듈을 찾을 수 없음

 오류 메시지

Module not found: Can't resolve '[module-name]'

 원인 : 필요한 패키지가 설치되지 않았거나, 잘못된 경로로 import 했을 때 발생합니다.

 해결 방법

  • 필요한 패키지 설치: npm install [module-name]
  • import 문의 경로 확인 및 수정

 예방책

  • 프로젝트의 의존성을 정기적으로 검토하고 업데이트하세요.
  • 절대 경로 import를 사용하여 경로 오류를 줄이세요.

 타입 오류 (TypeScript 사용 시)

 오류 메시지

Type error: Property '[property]' does not exist on type '[type]'

 원인 : 타입 정의가 잘못되었거나, 필요한 타입 선언이 누락되었을 때 발생합니다.

 해결 방법

  • 타입 정의 확인 및 수정
  • 필요한 경우 타입 선언 파일 (.d.ts) 추가

 예방책

  • ESLint와 TypeScript 컴파일러를 활용하여 개발 중에 타입 오류를 조기에 발견하세요.

런타임 오류

 'ReferenceError: document is not defined'

 원인 : 서버 사이드 렌더링 중에 브라우저 전용 API를 사용하려고 할 때 발생합니다.

 해결 방법

  • useEffect 훅을 사용하여 클라이언트 사이드에서만 실행되도록 코드 수정
  • 동적 import를 사용하여 해당 코드를 클라이언트 사이드로 지연 로딩

 예시

import dynamic from 'next/dynamic'
 
const ClientOnlyComponent = dynamic(() => import('../components/ClientOnlyComponent'), { ssr: false })

 'TypeError: Cannot read property '[property]' of undefined'

 원인 : 존재하지 않는 객체의 속성에 접근하려고 할 때 발생합니다.

 해결 방법

  • 옵셔널 체이닝 연산자 사용: object?.property
  • 기본값 설정: const { property = defaultValue } = object || {}

 예방책

  • 데이터의 구조와 타입을 명확히 정의하고, 타입 체크를 철저히 하세요.

라우팅 관련 문제

 404 Not Found 에러

 원인 : 라우트 파일이 올바른 위치에 없거나, 파일명이 잘못되었을 때 발생합니다.

 해결 방법

  • app 디렉토리 구조 확인
  • 파일명이 page.js (또는 page.tsx)인지 확인
  • 동적 라우트의 경우 대괄호 [] 사용 여부 확인

 예방책

  • 명확한 폴더 구조와 네이밍 컨벤션을 설정하고 따르세요.

 리다이렉션 무한 루프

 원인 : 잘못 구현된 리다이렉션 로직으로 인해 발생합니다.

 해결 방법

  • 리다이렉션 조건 재검토 및 수정
  • Next.js의 내장 리다이렉션 기능 활용

 예시

// next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-page',
        destination: '/new-page',
        permanent: true,
      },
    ]
  },
}

서버 사이드 렌더링 이슈

 'Error: Text content does not match server-rendered HTML'

 원인 : 서버에서 렌더링된 내용과 클라이언트에서 렌더링된 내용이 일치하지 않을 때 발생합니다.

 해결 방법

  • 서버와 클라이언트에서 동일한 데이터를 사용하는지 확인
  • 클라이언트 사이드 전용 로직을 useEffect 내부로 이동

 예방책

  • 서버 컴포넌트와 클라이언트 컴포넌트를 명확히 구분하세요.
  • 데이터 페칭 로직을 일관되게 유지하세요.

 CORS (Cross-Origin Resource Sharing) 오류

 원인 : 서버 사이드에서 외부 API를 호출할 때 CORS 설정이 되어 있지 않으면 발생합니다.

 해결 방법

  • API 라우트를 통해 외부 API 호출을 프록시
  • 외부 API 서버에 CORS 설정 요청

 예시

// app/api/proxy/route.js
import { NextResponse } from 'next/server';
 
export async function GET(request) {
  const res = await fetch('https://external-api.com/data', {
    headers: {
      'Content-Type': 'application/json',
    },
  });
  const data = await res.json();
  return NextResponse.json(data);
}

상태 관리 관련 오류

 상태 업데이트가 즉시 반영되지 않는 문제

 원인 : React의 상태 업데이트가 비동기적으로 처리되어 발생합니다.

 해결 방법

  • useEffect를 사용하여 상태 변화 감지 및 처리
  • 함수형 업데이트 사용

 예시

setCount(prevCount => prevCount + 1);

 예방책 :

  • 상태 업데이트의 비동기적 특성을 이해하고, 적절한 패턴을 사용하세요.

14장 테스팅과의 연관성

 18장의 오류 해결은 14장에서 다룬 테스팅과 밀접하게 연관됩니다. 단위 테스트, 통합 테스트, E2E 테스트를 통해 많은 오류를 사전에 발견하고 방지할 수 있습니다. 특히, 테스트 주도 개발(TDD) 방식을 적용하면 코드의 품질을 높이고 오류 발생 가능성을 줄일 수 있습니다.

실습 : 복잡한 오류 시나리오 분석 및 해결

 시나리오 : e-commerce 플랫폼에서 사용자가 제품을 장바구니에 추가한 후, 결제 페이지로 이동했을 때 간헐적으로 장바구니 정보가 사라지는 문제가 발생합니다.

 단계별 분석 및 해결

  1. 문제 재현
  • 다양한 브라우저와 디바이스에서 문제 재현 시도
  • 콘솔 로그 및 네트워크 요청 모니터링
  1. 가능한 원인 분석
  • 상태 관리 문제 : 전역 상태가 제대로 유지되지 않음
  • 라우팅 이슈 : 페이지 전환 시 상태 초기화
  • 서버 사이드 렌더링 문제 : 서버와 클라이언트 간 상태 불일치
  1. 디버깅
  • React DevTools를 사용하여 컴포넌트 트리 및 상태 변화 관찰
  • 네트워크 요청 분석하여 데이터 흐름 파악
  • 서버 로그 확인
  1. 원인 파악
  • 장바구니 상태가 로컬 스토리지에 저장되지 않아 페이지 새로고침 시 초기화됨
  1. 해결 방안 구현
  • 장바구니 상태를 로컬 스토리지에 동기화하는 로직 추가
// hooks/useCart.js
import { useState, useEffect } from 'react';
 
export function useCart() {
  const [cart, setCart] = useState([]);
 
  useEffect(() => {
    // 로컬 스토리지에서 장바구니 정보 로드
    const savedCart = localStorage.getItem('cart');
    if (savedCart) {
      setCart(JSON.parse(savedCart));
    }
  }, []);
 
  useEffect(() => {
    // 장바구니 상태가 변경될 때마다 로컬 스토리지에 저장
    localStorage.setItem('cart', JSON.stringify(cart));
  }, [cart]);
 
  const addToCart = (product) => {
    setCart(prevCart => [...prevCart, product]);
  };
 
  // 기타 장바구니 관련 함수들...
 
  return { cart, addToCart, /* 기타 함수들 */ };
}
  1. 테스트 및 검증
  • 단위 테스트 작성하여 useCart 훅의 기능 검증
  • 통합 테스트를 통해 페이지 간 이동 시 장바구니 상태 유지 확인
  • 다양한 시나리오에서의 E2E 테스트 수행
  1. 모니터링 및 사후 관리
  • 에러 로깅 시스템 구축하여 유사한 문제 조기 발견
  • 사용자 피드백 수집 및 분석

 이 실습을 통해 복잡한 오류를 체계적으로 분석하고 해결하는 과정을 경험할 수 있습니다. 실제 프로젝트에서는 이러한 접근 방식을 통해 효율적으로 문제를 해결하고, 애플리케이션의 안정성을 높일 수 있습니다.

 Next.js App Router 프로젝트에서 발생하는 오류들을 효과적으로 해결하기 위해서는 체계적인 접근과 깊은 이해가 필요합니다. 오류의 근본 원인을 파악하고, 적절한 해결 방법을 적용하는 것이 중요합니다. 또한, 예방적 조치를 통해 유사한 오류의 재발을 방지할 수 있습니다. 지속적인 학습과 경험을 통해 오류 해결 능력을 향상시키면, 더 안정적이고 효율적인 Next.js 애플리케이션을 개발할 수 있습니다.