FrontEnd Develop/Project : TODOMVC

Vite + React에서 이상적인 라우팅 구조 설계하기

Frisbeen 2025. 4. 2. 21:24

Vite와 React로 프로젝트를 구성할 때, 라우팅 구조를 어떻게 설계하느냐는 유지보수성과 가독성에 큰 영향을 미친다고 생각한다.

 

이 글에서는 React Router v6 기준으로, router.tsx 파일을 별도로 구성하여 라우팅 책임을 명확히 분리하는 구조를 소개한다.

기존 내가 했던 방식 (Vite)…

App.tsx에 라우팅 책임을 맡겼다.

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import NotFound from './pages/NotFound';

function App() {
  return (
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
  );
}

App.tsx의 SRP를 준수하지 못했다.

App.tsx는 사실 웹의 외피이다.

페이지도 아니고, 라우팅도 안하지만, 최상위 컴포넌트로서 지위는 있다.

뭐 아래와 같은걸 하겠다.

•	전역 스타일링 (styled-components, emotion, CSS reset 등)

•	상태 관리 Provider (Redux, Recoil, Zustand, Jotai, MobX 등)

•	쿼리 캐시 Provider (react-query, SWR 등)

•	테마 관리 (dark / light mode)

•	에러 바운더리 (ErrorBoundary)
•	언어 설정 (i18n)

•	토스트, 모달 등 앱 전역 공통 UI


발전된 버전 :기본 구조 설계

📦 src/
┣ 📄 main.tsx                ← 앱 진입점, RouterProvider 실행
┣ 📄 App.tsx                 ← 전역 상태 및 Provider 관리
┣ 📂router/
┃ ┗ 📄 router.tsx            ← 라우팅 정의 전용 파일
┣ 📂pages/                   ← 개별 페이지 컴포넌트들
┣ 📂components/              ← 재사용 가능한 UI 컴포넌트들

🧩 main.tsx _ 진입점

  1. 앱을 브라우저에 마운트 하는 최상위 Entry Point
  2. RouterProvider에 내가 만든 router.tsx 라우팅 객체를 주입

비유적 표현으로 웹의 심장박동 시작버튼

import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import { router } from './router/router';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

🧠 App.tsx - 전역 스탠드

앱의 컨트럴 타워로써

지금은 빈 껍데기지만 (Provider)이 없지만, 전역 상태나 테마 등을 추가하는 책임만을 부여한다.

function App({ children }: { children: React.ReactNode }) {
  return <>{children}</>;
}

export default App;

🧭 router.tsx - 길잡이 역할

router.tsx는 사용자의 경로(Path)에 따라 어떤 페이지를 렌더링할지를 정의하는 중심 파일이다.

즉, 앱의 ‘길 안내 네비게이터’ 역할을 한다.”

import { createBrowserRouter } from 'react-router-dom';
import App from '../App';
import Layout from '../layouts/Layout';
import Home from '../pages/Home';
import NotFound from '../pages/NotFound';

export const router = createBrowserRouter([
  {
    path: '/',
    element: (
      <App>
        <Layout />
      </App>
    ),
    children: [
      { path: '', element: <Home /> },
      { path: '*', element: <NotFound /> },
    ],
  },
]);

💡 왜 이렇게 구성할까?

  1. Single Responsibility
    • App.tsx는 앱 전체에 필요한 전역 Provider만 담당
    • router.tsx는 페이지 이동과 관련된 라우팅 정의만 담당
  2. 테스트 및 유지보수 용이
    • 각각의 책임이 분리되므로, 변경 시 영향을 최소화할 수 있음
  3. Next.js 스타일을 React에서도 구현 가능
    • 구조적으로 레이아웃/라우팅/전역 상태 분리를 통해 Next.js의 장점을 일부 흡수할 수 있음

결론

Vite + React 환경에서는 코드 기반 라우팅을 어떻게 구조화하느냐에 따라 프로젝트의 품질이 결정된다.

router.tsx를 통해 명확하게 라우팅 책임을 분리하고,

App.tsx를 통해 전역 상태를 관리하는 구조는 확장성과 유지보수성을 크게 높여주는 효과를 기대 할 수 있다.

'FrontEnd Develop > Project : TODOMVC' 카테고리의 다른 글

Zustand X Generic 심층분석.  (0) 2025.04.09