기타

[Project_react-router-file-routing] 01 - 프로젝트 구성하기

joseph0926 2024. 10. 9. 13:43

프로젝트 시작점

react에서는 주로 react-router-dom을 이용해서 라우팅을 처리하고, next.js에서는 내장된 파일/폴더 기반 라우팅을 이용합니다

저는 주로 next.js를 사용해서 파일/폴더 기반 라우팅이 더 익숙하였고, 이를 react-router-dom에서도 사용하고싶은 마음에 시작하였습니다.

 

프로젝트 아이디어

기본적인 아이디어는 next.js의 폴더 기반 라우팅을 그대로 구현하는거였습니다.

즉 [폴더명]/page.tsx 구조로 제한을 걸고 폴더명이 path가 되는 방식입니다

 

이를 위해서는 내부적으로 폴더/파일 구조를 탐색하고 이 특정 패턴의 폴더/파일 경로를 가져와서 react-router object로 바꾸는 방법이 있다고 생각하였습니다

 

실제 구현

`import.meta.glob()`를 활용하는게 핵심이였습니다

이를 통해 `/src/pages/**/page.{jsx,tsx}` 패턴의 파일/폴더 경로를 모두 가져옵니다

const modules = import.meta.glob('/src/pages/**/page.{jsx,tsx}');

 

이러면 아래와 같은 결과가 나오게될것입니다

{
  '/src/pages/home/page.tsx': () => import('/src/pages/home/page.tsx'),
  '/src/pages/about/page.tsx': () => import('/src/pages/about/page.tsx'),
  ...
}

 

이제 이 객체를 돌면서 key와 value를 적절하게 포멧해줍니다

예를들어 "/src/pages/**/page.{jsx,tsx}" 에서 앞의 "/src/pages"는 삭제되어야하고,
뒤에 존재하는 "page.{jsx,tsx}"도 경로에 들어가면 안됩니다

export function formatPath(filePath: string): string {
  /** 윈도우 경로 구분자 처리 */
  const normalizedPath = filePath.replace(/\\/g, '/');
  let path = normalizedPath
    .replace(/^\/src\/pages/, '') // 폴더 경로에서 `path`에 포함되지 않을 부분 제거
    .replace(/\/page\.(jsx|tsx)$/, '') // 폴더 경로에서 page.tsx or page.jsx 제거
    .replace(/\[([^\]]+)\]/g, ':$1'); // [id] -> :id 로 변환

  if (path === '') {
    path = '/';
  }

  return path;
}

 

또한 react-router Object에는 `path`와 `element`가 필요합니다

위의 `modules`의 결과를 보시면 알겠지만 dynamic 임포트를 통해 가져오므로 React.lazy를 통해 처리해주어야합니다

const element = React.lazy(modules[filePath] as any);

 

이제 이렇게 구성된 object를 라우터에 적용해야하므로 아래와 같이 처리할수있습니다

const element = useRoutes(routes);

 

이러면 "/src/pages/home/page.tsx"가 /home에 접근시 렌더링되는 것을 확인할 수 있습니다

 

자세한 내용은 아래 깃허브를 참고해주세요

[깃허브 - react-router-file-routing]

 

GitHub - joseph0926/react-router-file-routing: A library to support folder-based routing of next.js to react-router-dom

A library to support folder-based routing of next.js to react-router-dom - joseph0926/react-router-file-routing

github.com

 

한계점

아직 시작단계라 너무 많은 한계점이 존재하지만 일단 가장 큰 한계는 `vite`외 환경에서는 사용 불가능한 점입니다.

하지만 아직 시작단계이므로 우선 `vite` 환경에서 최대한 잘 동작하게 한 후 확장해보려합니다

 

다음 단계

동적 라우트를 처리하려합니다

`/src/pages/[id]/page.tsx` -> /:id 

 

최종 목표

next.js의 폴더/파일 기반 시스템을 완전히 카피하는게 목표입니다

(loading.tsx, error.tsx ... 등)