thumbnail

Generate Router의 새로운 버전: 타입 안전한 라우팅의 진화

생성일2024. 12. 10.
태그
작성자지한솔

notion image
Generate Router가 더 강력한 타입 안전성을 제공하는 새로운 버전으로 돌아왔습니다. 기존 버전에서는 사용자가 직접 RoutePath를 정의하고 useRouterLink를 래핑해야 했지만, 이제는 override 속성을 통해 이를 자동으로 처리할 수 있습니다.
이제 useRouter, Link, usePathname, useSearchParams에 대한 타입이 자동으로 추론되며, 동적 라우트의 파라미터가 누락되거나 잘못된 경로를 입력하는 경우 컴파일 타임에 에러가 발생합니다. 이 기능은 생산성을 높이고, 타입 안정성을 극대화합니다.

주요 변경 사항

기존 버전과 비교했을 때, 새로운 버전의 핵심 변경 사항은 타입 오버라이딩 기능입니다.
기존
변경 후
RoutePath를 직접 정의해야 했음
override 옵션으로 자동으로 정의됨
useRouter에 타입이 적용되지 않음
useRouterpush, replace에 자동 타입 적용
잘못된 경로에 대한 런타임 에러 발생
컴파일 타임 에러 발생
수동으로 Link의 href 타입 지정 필요
Linkhref에 타입 자동 적용
이제 사용자는 useRouterLink에 대한 수동 타입 설정 없이도 자동 완성, 타입 검증이 가능하며, 라우트 경로의 변경에 따른 자동 타입 업데이트도 지원됩니다.

타입 오버라이딩의 구현 방식

이 기능의 핵심은 Next.js 모듈을 직접 오버라이딩하는 것입니다. 오버라이딩된 코드는 아래와 같이 구성됩니다.

next/router 오버라이딩

declare module 'next/router' { interface UrlObject { pathname: RoutePath; query?: { [key: string]: string | number | boolean | readonly string[] | undefined }; hash?: string; } interface NextRouter extends Omit<import('next/dist/shared/lib/router/router').NextRouter, 'push' | 'replace'> { push( url: RoutePath | UrlObject, as?: string | UrlObject, options?: TransitionOptions ): Promise<boolean>; replace( url: RoutePath | UrlObject, as?: string | UrlObject, options?: TransitionOptions ): Promise<boolean>; } export function useRouter(): NextRouter; }

next/navigation 오버라이딩

declare module 'next/navigation' { interface NavigationUrlObject { pathname: RoutePath; query?: { [key: string]: string | number | boolean | readonly string[] | undefined }; hash?: string; } interface NavigationRouter extends Omit<import('next/dist/shared/lib/app-router-context.shared-runtime').AppRouterInstance, 'push' | 'replace'> { push(href: RoutePath | NavigationUrlObject, options?: { scroll?: boolean }): void; replace(href: RoutePath | NavigationUrlObject, options?: { scroll?: boolean }): void; query: { [key: string]: string | string[] | undefined }; } export { NavigationRouter }; export function useRouter(): NavigationRouter; export function usePathname(): RoutePath; export function useSearchParams(): URLSearchParams & { get(key: string): string | null; getAll(): { [key: string]: string | string[] }; }; }

next/link 오버라이딩

declare module 'next/link' { export interface LinkProps extends Omit<import('next/dist/client/link').LinkProps, 'href'> { href: | RoutePath | { pathname: RoutePath; query?: { [key: string]: | string | number | boolean | readonly string[] | undefined; }; hash?: string; }; } export default function Link(props: LinkProps): JSX.Element; }

새로운 기능의 활용 방법

CLI 명령어로 활성화

npx generate-router ./pages ./types/routes.d.ts --override # 또는 축약형 npx generate-router ./pages ./types/routes.d.ts -o

코드 예시

Before (기존 코드)

import { useRouter } from 'next/router'; import Link from 'next/link'; const Component = () => { const router = useRouter(); // ❌ 런타임 에러 발생 가능 router.push('/invalid-route'); return ( <> <Link href="/invalid-route">잘못된 링크</Link> </> ); };

After (변경 후)

import { useRouter } from 'next/router'; import Link from 'next/link'; const Component = () => { const router = useRouter(); // ✅ 컴파일 에러 발생 (올바르지 않은 경로) router.push('/invalid-route'); // ❌ // ✅ 자동 완성 기능으로 올바른 경로 자동 제안 router.push('/user/123'); return ( <> {/* ❌ 잘못된 경로 - 컴파일 에러 발생 */} <Link href="/invalid-route">잘못된 링크</Link> {/* ✅ 자동완성과 타입 검증이 지원됨 */} <Link href="/user/123">사용자 페이지</Link> </> ); };

추가된 에러 핸들링

동적 라우트 파라미터 누락 방지:
router.push('/user'); // ❌ 컴파일 에러 - id 파라미터 누락
존재하지 않는 경로 사용 방지:
router.push('/nonexistent-path'); // ❌ 컴파일 에러 - 존재하지 않는 경로
동적 파라미터 자동 추론:
// 경로가 /post/[slug]라면 router.push('/post/some-slug'); // ✅ 정상 동작 router.push('/post'); // ❌ 컴파일 에러 - slug 누락

마이그레이션 가이드

  1. 패키지 업데이트:
npm update generate-router
  1. CLI 명령어에 --override 추가:
npx generate-router ./pages ./types/routes.d.ts --override
  1. 기존 코드 수정:
      • router.push('/invalid-path')과 같은 잘못된 경로 수정
      • Linkhref 속성에 잘못된 경로가 있으면 수정

주요 이점

이점
설명
타입 안전성 향상
잘못된 경로에 대해 컴파일 에러 발생
자동 완성 지원
router.push, Linkhref에 자동 완성 지원
유지보수 용이성
라우트 경로 변경 시 자동 타입 업데이트

마무리

이번 업데이트로 Generate Router는 더 강력한 타입 안전성을 제공합니다. 기존의 불완전한 런타임 에러를 컴파일 타임 에러로 전환하여 더 빠르고 안전한 개발 환경을 제공합니다.
코드 품질 향상, 생산성 향상, 유지보수 편의성을 모두 제공하는 이 기능을 통해 더욱 안전하고 직관적인 라우팅 개발을 할 수 있습니다.
자세한 코드는 Github 저장소에서 확인이 가능하며 NPM 저장소 에도 배포되어 있으니 한번 확인해 주세요!
만약 기존 프로젝트에 적용하지 않았다면, 지금 바로 적용해보세요!
여러분의 라우팅 환경이 더 강력하고 안전해질 것입니다. 🚀