[Front] MBTI 프로젝트의 마이그레이션 여정기

devicii·2025년 3월 21일
2

Front

목록 보기
1/8
post-thumbnail

프롤로그

4년 전 React.js를 처음 알게 되면서 학습 목적으로 만들었던 MBTI 테스트 프로젝트를 Next.js로 마이그레이션 한 경험을 적어보려 한다. 단순한 기술 전환을 넘어 프로젝트를 한 단계 업그레이드하는 과정에서 배운 점과 그리고 예상치 못한 도전과 해결책까지 기록하려 한다.

1.프로젝트 소개 - 왜 MBTI 테스트임?

리액트가 한창 떠오르던 시절 친구들 사이에서 MBTI 테스트가 엄청 핫한 걸 보고, "직접 만들어보면 어떨까?"라는 생각으로 시작했다. 마침 미니 프로젝트 할 적합한 사이즈였다.

기존 React 프로젝트 구성

  • Create React App으로 구축
  • 스타일링: Styled-components
  • 배포: Netlify

🤔 2.왜 Next.js로의 마이그레이션을 결심했나?

  1. SEO 최적화의 필요성

    • CRA로 만든 SPA는 검색 엔진 최적화에 한계가 있었다.
    • 더 많은 사람들이 나의 MBTI 테스트를 발견할 수 있게 하고 싶었다.
  2. 성능 개선 욕구

    • Next.js를 적극적으로 활용해 이미지 최적화 및 더 빠른 초기 페이지 로딩을 원했다.
    • 모바일에서의 사용자 경험을 개선하고 싶었다.

3.마이그레이션 계획 세우기

미니 프로젝트이지만 마이그레이션을 시작하기 전에 명확한 계획이 필요했다.
2무작정 코드를 옮기는 것보다 체계적인 설계가 중요하다고 생각했다. 그래서 아래와 같은 순서로 마이그레이션을 진행해 보았다.

1. 프로젝트 구조 분석 및 설계
2. Next.js 프로젝트 설정
3. 컴포넌트 이전 및 적응
4. 라우팅 시스템 재구성
5. 상태 관리 재검토
6. API 라우트 구현
7. SEO 최적화
8. 배포 및 모니터링

4.실제 마이그레이션 과정

4-1 프로젝트 구조 설계

기존 CRA 프로젝트와 Next.js의 구조적 차이를 파악하는 것부터 시작

마이그레이션 전 React.js 구조

📂 src
  ├─ app.jsx # 첫 페이지
  ├─ App.css # 글로벌 css

📂 common/api
  ├─ countriesApi.json # 결과 json 파일
  ├─ questionApi.json # 질문 json 파일
  
📂 components # 컴포넌트 모아놓는 디렉토리
  ├─ countries
  ├─ home
  ├─ option
  ├─ shareSNS
  

마이그레이션 후 Next.js 구조

📂 src/app
  ├─ layout.tsx
  ├─ page.tsx
  ├─ tripMBTI
  └─ page.tsx 
  └─ result
     └─ [id].js
📂 components  # 컴포넌트 모아놓는 디렉토리
  ├─ common
  ├─ test
  └─ result
📂 hooks  # 공용 훅 디렉토리
📂 styles # 스타일 디렉토리
📂 public # 이미지 디렉토리

4-2 환경 설정의 차이점 극복하기

Next.js로 넘어오면서 환경 변수, 빌드 설정 등 여러 부분에서 차이가 있었다.

환경 변수 처리의 차이점과 해결책


// 환경 변수 네이밍 규칙
# React에서 
REACT_APP_API_URL=https://api.example.com

# Next.js에서

NEXT_PUBLIC_API_URL=https://api.example.com

// 해결방법 : Next에서 모든 클라이언트 측에서 접근해야 하는 환경 변수는 NEXT_PUBLIC_ 접두사를 붙임

빌드 설정 차이점과 해결책


 1. 설정 파일 구조
//  React에서 
// package.json의 scripts
// react-scripts 설정 오버라이드를 위한 별도 설정 (eject 또는 react-app-rewired 필요)

# Next.js에서
next.config.js 파일을 통한 설정

// next.config.js

module.exports = {
  reactStrictMode: true,
  env: {
    customKey: 'customValue',
  },
  // webpack 설정 커스터마이징
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // 커스텀 웹팩 설정 추가
    return config
  },
}

//  2. 라우팅 시스템 전환: 가장 큰 변화

// React Router에서 Next.js의 파일 기반 라우팅으로 전환하는 과정은 생각보다 복잡했다.
// Next.js에서는 URL 파라미터 처리 방식이 완전히 달라진다.

// 기존 React Router 코드

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/test" component={Test} />
        <Route path="/result/:type" component={Result} />
      </Switch>
    </Router>
  );
}

// Next.js 파일 기반 라우팅 
- `app/index.js` → 홈페이지
- `app/test.js` → 테스트 페이지
- `app/result/[type].js` → 결과 페이지

// pages/result/[type].js
import { useRouter } from 'next/router';

export default function Result() {
  const router = useRouter();
  const { type } = router.query;
  
  // type을 기반으로 결과 표시
  return (
    <div>
      <h1>{type} 유형의 결과입니다!</h1>
      {/* 결과 컴포넌트 */}
    </div>
  );
}

4-3. 이미지 최적화

Next.js의 Image 컴포넌트를 사용하면서 이미지 최적화의 중요성을 실감했다.

기존 방식:

<img src="/images/results/INFP.jpg" alt="INFP 결과 이미지" />

Next.js의 Image 컴포넌트:

import Image from 'next/image';

<Image 
  src="/images/results/INFP.jpg"
  alt="INFP 결과 이미지"
  width={400}
  height={300}
  layout="responsive"
/>

처음에는 width와 height를 지정하는 것이 번거로웠지만, 성능 향상과 레이아웃 시프트 방지 효과를 보고 나니 충분히 가치 있는 변화였다.

5.마이그레이션 후 개선된 점들

5-1 성능 측정 결과

마이그레이션 전후의 성능을 아래 링크의 글을 참고하여 측정해 봤다.
https://devocean.sk.com/blog/techBoardDetail.do?ID=165395

측정 항목CRA (이전)Next.js (이후)개선율
첫 페이지 로딩4.92.9 초40.8%
접근성82점93점13.4%
SEO 점수82점100점22.0%

5-2 SEO 개선

// pages/result/[type].js
import Head from 'next/head';

export default function Result({ typeData }) {
  return (
    <>
      <Head>
        <title>{typeData.title} | MBTI 테스트 결과</title>
        <meta name="description" content={typeData.description} />
        <meta property="og:title" content={typeData.title} />
        <meta property="og:description" content={typeData.description} />
        <meta property="og:image" content={typeData.imageUrl} />
      </Head>
      {/* 페이지 내용 */}
    </>
  );
}

각 MBTI 결과 페이지별로 최적화된 메타 태그를 적용하고 구글 및 네이버 검색 엔진에 색인 등록하니 노출이 확실히 증가했다.

5-3 사용자 경험 개선

  • 페이지 전환 속도 향상
  • 이미지 로딩 최적화
  • 모바일 환경에서의 성능 및 접근성 개선

6. 예상치 못했던 도전과 해결책

6-1. 챌린지 1: CSS-in-JS와 SSR의 충돌

Styled-components가 서버 사이드 렌더링과 충돌하는 문제가 발생했다.

해결책: tailwind 도입으로 정상화.

7.배운 점과 앞으로의 계획

7-1 배운 점

  1. 프레임워크 전환은 단순 마이그레이션이 아닌 재설계 과정

    • 기존 코드를 그대로 옮기는 것이 아니라, 새 프레임워크의 철학에 맞게 재구성하는 것이 중요하다는 걸 배웠다. 현업이라면 트레이드오프를 왜 고민하는지... 레거시라고 불리는 php랑 jquery로 잘 돌아가는 코드를 마이그레이션 할 때 발생하는 트레이드오프를 감당할 수 있는지 없는지...?
  2. 성능 최적화의 중요성

    • Next.js의 다양한 렌더링 방식(SSR, SSG, ISR)을 적절히 사용해서 활용하는 것이 중요하다.

7-2 앞으로의 계획

  1. 국제화(i18n) 지원 추가

    • 영어, 일본어 등 다양한 언어 지원해서 배포
  2. RAG랑 VectorDB를 활용

    • GPT API를 활용하는데 RAG와 VectorDB를 활용해 더 정확한 AI의 더 정확한 여행지 추천 기능 강화

8. 마무리하며


조금의 애착이 있는 쁘띠 미니 프로젝트를 React에서 Next.js로의 마이그레이션은 단순한 기술 스택 변경 이상의 가치가 있었다. SEO를 잘해서인지 활성 사용자도 매일 조금씩이라도 들어오는 중이다.
프로젝트 구조를 재검토하고, 성능과 사용자 경험을 개선하고 GPT API를 활용해 프롬프팅 하는 좋은 기회였다.

profile
흘러가는대로 사는

2개의 댓글

comment-user-thumbnail
2025년 3월 21일

인상깊네요...

1개의 답글