파일 기반 라우팅과 일반적인 라우팅 + 간단하게 구현해보기

2025. 3. 21. 11:27개발/react

반응형

 

 

📂 파일 기반 라우팅

  • 설명: pages 폴더 구조를 기반으로 자동으로 경로를 설정하는 방식
  • 예시:
     

🔧 일반적인(수동) 라우팅

  • 설명: 개발자가 직접 react-router-dom 등을 사용해 Routes 컴포넌트를 정의하는 방식
  • 예시:
     

 

 

 

 

 

장단점

 

 

 



✅ 간단한 프로젝트 (빠른 개발) 파일 기반 라우팅
✅ Next.js 같은 풀스택 환경 파일 기반 라우팅
✅ 대규모 프로젝트 일반적인 라우팅
✅ 복잡한 라우팅 & 사용자 정의가 필요 일반적인 라우팅

 

 

 

 

직접 구현해 보기 >> 권한 설정을 각 페이지 안에서 해줘야 함 

import { BrowserRouter, Route, Routes } from "react-router";

// Modules 타입 정의
type Modules = {
    [key: string]: {
        default: React.ComponentType;
    }
};

// MODULES의 타입 단언(type assertion)
const rawModules: Record<string, unknown> = import.meta.glob('/src/pages/**/*.tsx', { eager: true });

// MODULES를 Modules 타입으로 검증 및 캐스팅
const MODULES: Modules = Object.fromEntries(
    Object.entries(rawModules).map(([key, value]) => {
        // 각 모듈이 기본(default) React 컴포넌트를 내보내는지 검사
        if (typeof value === 'object' && value !== null && 'default' in value) {
            return [key, value as { default: React.ComponentType }];
        }
        throw new Error(`Module at ${key} does not conform to expected type.`);
    })
);

// 모듈에서 라우트를 생성하는 함수
const generateRoutes = (modules: Modules) => {
    return Object.keys(modules).map(filePath => {
        const pathParts = filePath.split('/');
        const fileName = pathParts.pop() ?? ""; // Extract file name

        // Handle dynamic segments
        const routePath = pathParts
            .slice(3) // Remove '/src/pages/' part
            .map(part => part.startsWith('[') && part.endsWith(']')
                ? `:${part.slice(1, -1)}` // Convert '[id]' to ':id'
                : part
            )
            .join('/')
            .toLowerCase();

        // Use the file name if it's the dynamic segment
        const Component = modules[filePath].default;
        return <Route key={routePath} path={routePath} element={<Component />} />;
    });
};

const Router = () => {
    return (
        <BrowserRouter>
            <Routes>
                {generateRoutes(MODULES)}
            </Routes>
        </BrowserRouter>
    );
};

export default Router;
반응형