Next.js Middleware, 더 간결하고 효율적으로 관리하는 방법

Next.js에서 middleware.ts를 사용하면 글로벌하게 미들웨어를 적용할 수 있습니다. 하지만, 실제 개발 과정에서 다음과 같은 불편함을 겪을 수 있습니다.

  • 모든 요청에 적용됨: 특정 라우트에만 미들웨어를 적용하고 싶어도 별도의 처리가 필요합니다.
  • 복잡한 조건문: if문을 통해 특정 라우트를 검사하고 실행하는 방식이 번거롭고 유지보수가 어렵습니다.

이러한 문제를 해결하기 위해 next-middleware-enhancer를 개발하게 되었습니다. 이제, 제가 어떻게 개선하였는지에 대해 알려드리고자 합니다!

기존 방식의 문제점

1. 모든 요청에 적용됨

기본적으로 Next.js의 middleware.ts는 모든 요청에 대해 실행됩니다. 특정 경로에서만 실행하고 싶다면, if문을 사용하여 경로를 직접 필터링해야 합니다.

import { NextRequest, NextResponse } from "next/server"; export function middleware(req: NextRequest) { console.log(`Request received: ${req.nextUrl.pathname}`); return NextResponse.next(); }

이 방식은 모든 요청을 처리하기 때문에 불필요한 실행이 발생할 수 있습니다.

2. 복잡한 조건문 문제

특정 경로에서만 인증을 적용해야 할 경우, if문을 이용해 직접 필터링해야 합니다. 예를 들어, /admin 경로에서만 인증을 적용하려면 다음과 같이 작성해야 합니다.

import { NextRequest, NextResponse } from "next/server"; export function middleware(req: NextRequest) { if (req.nextUrl.pathname.startsWith("/admin")) { if (!req.headers.get("Authorization")) { return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); } } return NextResponse.next(); }

이러한 방식은 미들웨어가 많아질수록 코드가 길어지고 관리가 어려워질 수 있습니다.

next-middleware-enhancer 이렇게 활용해보세요

이 라이브러리는 Next.js의 미들웨어를 보다 선언적으로 사용할 수 있도록 설계되었습니다.

npm install next-middleware-enhancer or

pnpm add next-middleware-enhancer

import { NextRequest, NextResponse } from "next/server"; import { createMiddleware } from "next-middleware-enhancer"; const logMiddleware = (req: NextRequest) => { console.log(`Request to: ${req.nextUrl.pathname}`); }; const authMiddleware = (req: NextRequest) => { if (!req.headers.get("Authorization")) { return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); } }; const { middleware, config } = createMiddleware([{ matcher: "/admin", handler: [logMiddleware, authMiddleware] }]); export { middleware, config };

핵심 기능

  • 라우트 기반 미들웨어 적용: 특정 경로에만 미들웨어를 선언적으로 적용 가능.
  • 다중 미들웨어 실행 지원: 여러 개의 미들웨어를 순차적으로 실행 가능.
  • 자동 응답 처리: 일치하는 미들웨어가 없을 경우 NextResponse.next() 반환.

이러한 기능을 통해 미들웨어를 보다 체계적으로 관리할 수 있습니다.


라이브러리 개발 과정에서 배운 것들

1. Monorepo 환경에서 라이브러리 개발

이번 프로젝트는 pnpm을 사용하여 Monorepo 환경에서 진행되었습니다. 이를 통해

  • 의존성 중복 감소: 동일한 패키지를 여러 번 설치하는 문제를 방지할 수 있었습니다.
  • 실제 사용 환경을 반영한 테스트: E2E 테스트를 통해 라이브러리가 Next.js 프로젝트에서 정상적으로 동작하는지 검증할 수 있었습니다.

2. E2E 테스트와 API 테스트

라이브러리의 안정성을 검증하기 위해 다양한 테스트 환경을 활용했습니다:

  • E2E 테스트: Playwright를 사용하여 header 값을 검증하는 방식으로 미들웨어 기능을 테스트했습니다.
  • API 테스트: Vitest를 활용하여 API 요청과 응답을 테스트하며, 미들웨어가 올바르게 동작하는지 확인했습니다.

이러한 테스트 방식을 도입함으로써 실사용 환경에서도 라이브러리가 안정적으로 동작할 수 있도록 했습니다.

3. Vite와 Rollup을 활용한 빌드 구성

라이브러리를 배포하기 위해 Vite의 라이브러리 모드를 사용했고, 빌드 과정에서는 Rollup을 활용하여 다양한 환경을 지원하는 방식으로 구성했습니다.

  • ESM (ES Modules): 최신 프론트엔드 프로젝트와 호환.
  • CJS (CommonJS): 기존 Node.js 환경과의 호환성 고려.

Next.js에서는 사실 CommonJS가 필수는 아니었지만, Rollup을 활용하면서 빌드 시스템을 다루는 방법에 대해서 학습할 수 있었습니다!


자세히 확인해보시려면 아래 Github과 NPM으로!

링크 미리보기 이미지GitHub - lurgi/nextjs-middleware-monorepoContribute to lurgi/nextjs-middleware-monorepo development by creating an account on GitHub.

링크 미리보기 이미지next-middleware-enhancerEnhance Next.js middleware with ease. Latest version: 1.1.6, last published: 3 months ago. Start using next-middleware-enhancer in your project by running `npm i next-middleware-enhancer`. There are no other projects in the npm registry using next-middleware-enhancer.

Next.js 프로젝트에서 미들웨어를 보다 쉽게 활용하는 데 도움이 되길 바랍니다. 감사합니다!

여러분의 피드백을 기다립니다!

이 라이브러리를 사용하면서 개선이 필요하다고 느끼신 부분이 있다면, 아래 링크를 통해 의견을 남겨주세요. 적극적으로 반영하겠습니다!

🔗 next-middlewware-enhancer 피드백 남기기