params를 await 하고, SVG를 컴포넌트로 파싱하고, fixture를 버리세요: 프론트엔드 DX를 바꾸는 3가지 실무 패턴

params를 await 하고, SVG를 컴포넌트로 파싱하고, fixture를 버리세요: 프론트엔드 DX를 바꾸는 3가지 실무 패턴

타입으로 검증을 앞당기고, 디자인 에셋을 자동화하고, 스펙 기반 목 서버로 fixture 지옥에서 탈출하는 구체적인 워크플로우를 해부합니다.

Next.js App Router SVG React 컴포넌트 Mock Server Parse Don't Validate 프론트엔드 DX TypeScript OpenAPI 디자인 시스템
광고

프론트엔드 개발자라면 누구나 한 번쯤 이런 경험이 있을 겁니다. Figma에서 아이콘 SVG를 받아서 <img> 태그로 넣었는데 색상이 안 바뀌고, Next.js 버전 올렸더니 params가 갑자기 Promise가 되어 있고, 백엔드 필드 하나 바뀌었는데 /fixtures 폴더의 JSON 수십 개를 손으로 고치고 있는 자신을 발견하는 거죠. 이번 주 눈에 띈 세 가지 소스를 엮어보니, 결국 하나의 원칙으로 수렴합니다. "검증하지 말고, 파싱하라."

1. Next.js App Router: paramsPromise가 된 이유를 1px까지 파고들기

velog의 Next.js App Router 라우팅 정리 글을 보면, App Router에서 searchParamsparams가 이제 Promise 형태로 전달된다는 점이 명확히 정리되어 있습니다. 사용자 입장에서는 URL이 똑같이 /book/100인데, 개발자 입장에서는 const { id } = await params로 한 줄이 바뀐 거죠.

사실 이 변경이 왜 중요하냐면, 기획자가 "상세 페이지에서 이 데이터 보여주세요"라고 할 때 발생하는 디자인-개발 갭 때문입니다. Page Router 시절에는 useRouter().query로 클라이언트에서 꺼냈는데, App Router에서는 서버 컴포넌트가 기본이니까 async 함수 안에서 await로 파싱해야 합니다. 여기서 TypeScript 타입 정의가 Promise<{ id: string }>으로 바뀌었다는 건, 런타임에 "이 값이 있겠지"라고 기대하는 게 아니라 컴파일 타임에 비동기 처리를 강제한다는 뜻입니다.

이게 바로 GeekNews에서 화제가 된 Rust의 '검증하지 말고 파싱하라' 원칙과 정확히 같은 맥락입니다. Rust에서 NonZeroF32 타입을 만들어서 0으로 나누는 실수를 컴파일 타임에 잡는 것처럼, Next.js도 paramsPromise로 감싸서 "await 안 하면 타입 에러"라는 울타리를 친 겁니다. 단순히 API가 바뀐 게 아니라, 프레임워크 차원에서 잘못된 사용을 표현 불가능하게 만든 설계 결정이에요.

2. SVG → React 컴포넌트: 디자인 시스템의 '파싱 레이어'

dev.to의 SVG to React Components 가이드는 실무에서 반복되는 고통을 정면으로 다룹니다. classclassName, stroke-widthstrokeWidth... Figma에서 Export한 SVG를 JSX에 그대로 붙여넣으면 에러가 뜨는 그 순간, 우리 모두 한숨을 쉬어본 적 있잖아요.

수동 변환의 문제는 휴먼 에러입니다. fill-rule은 고쳤는데 clip-path를 놓치는 식이죠. 여기서도 "검증하지 말고 파싱하라" 원칙이 적용됩니다. SVGR 같은 자동화 도구를 빌드 파이프라인에 끼워넣으면, SVG 원본이 입력이고 React.FC<React.SVGProps<SVGSVGElement>> 타입이 적용된 컴포넌트가 출력입니다. 중간에 사람이 속성 이름을 하나하나 검증할 필요가 없어요. 도구가 파싱하니까요.

특히 디자인 시스템을 운영하는 팀이라면, 이 자동화 파이프라인의 유무가 번들 사이즈에도 직결됩니다. <img src="icon.svg">는 트리쉐이킹이 안 되지만, 컴포넌트로 변환하면 실제로 import한 아이콘만 번들에 포함됩니다. Lighthouse 점수에서 "Reduce unused JavaScript" 경고가 뜨는 팀이라면, 이 워크플로우 전환만으로도 체감되는 차이가 있을 겁니다.

3. Mock Server: fixture 폴더라는 '거짓말 저장소'를 버리기

dev.to의 Stop Writing JSON Fixtures 글의 첫 문장이 너무 아팠습니다. "Every codebase I've inherited has a /fixtures folder. Inside: hundreds of JSON files, half of them stale." 백엔드에서 필드 하나 바꿨는데 프론트엔드 테스트는 여전히 통과하고, 프로덕션에서 터지는 그 패턴이요.

OpenAPI 스펙 기반 Mock Server는 스펙이 곧 소스 오브 트루스라는 전제에서 출발합니다. NEXT_PUBLIC_API_URL 환경변수 하나만 바꾸면 목 서버와 실제 API를 스위칭할 수 있는 구조는, 프론트엔드 개발자가 백엔드 완성을 기다리지 않고 작업할 수 있게 해줍니다. 사실 이건 flexbox로 해결되는 레이아웃 문제처럼 단순한 건데, 의외로 많은 팀이 아직 JSON 파일을 수동으로 복붙하고 있어요.

여기서도 패턴은 동일합니다. fixture JSON은 API 응답의 복사본을 수동으로 검증하는 방식이고, 스펙 기반 목 서버는 OpenAPI 정의를 파싱해서 자동으로 응답을 생성하는 방식입니다. 스펙이 바뀌면 목도 바뀌니까 드리프트가 없죠.

세 패턴을 관통하는 하나의 원칙

정리하면 이렇습니다:

문제 검증(Validate) 방식 파싱(Parse) 방식
라우트 파라미터 런타임에 query.id 존재 여부 체크 Promise<{ id: string }> 타입으로 await 강제
SVG 속성 변환 개발자가 눈으로 하나씩 확인 빌드 도구가 camelCase 자동 변환
API 테스트 데이터 /fixtures JSON 수동 관리 OpenAPI 스펙에서 목 응답 자동 생성

Rust 생태계에서 "불법 상태를 표현 불가능하게 만들라"는 원칙이 Hacker News에서 172개 댓글이 달릴 만큼 뜨거운 이유가, 결국 프론트엔드에서도 그대로 적용되기 때문입니다. Next.js가 paramsPromise로 바꾼 것, SVGR이 속성 변환을 자동화한 것, 스펙 기반 목 서버가 fixture를 대체한 것—전부 사람의 주의력에 의존하는 검증을, 도구와 타입 시스템이 수행하는 파싱으로 대체한 사례입니다.

프론트엔드 DX(Developer Experience)는 결국 "실수할 수 있는 지점을 얼마나 줄이느냐"의 문제입니다. 여기서 로딩 스켈레톤 넣으면 어떨까요... 같은 이야기가 아니라, 아예 잘못된 코드가 컴파일되지 않게, 잘못된 에셋이 빌드되지 않게, 잘못된 응답이 테스트를 통과하지 않게 만드는 구조적 접근이요. 2025년의 프론트엔드는 "꼼꼼한 개발자"가 아니라 "실수를 허용하지 않는 파이프라인"이 품질을 보장하는 시대로 가고 있습니다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요