Template Library 시리즈의 세 번째 글은 Next.js 12 적용에 대한 이야기입니다.
Next.js 12 업데이트 소식 나온 지 거의 두 달이 지나가고 있네요. Template Library에서 먼저 적용하여 테스트해보고 실무에도 적용한 지도 한 달이란 시간이 넘게 지나가고 있습니다. 사실 이 글은 Template Library를 적용하고 바로 작성하고자 했지만, 정작 적용 후 개인적으로 너무 바쁜 시간을 보내어 지금에서야 작성하게 되었습니다.
<Image />
AVIF Support: Opt-in for 20% smaller imagesNext.js 12에서 업데이트된 내용을 위와 같이 8가지입니다만, 실제 제가 Template Library에 적용하고 실무에서 사용하고 있는 사항은 Middleware뿐이어서 이 글에서는 Middleware에 대한 정리만 진행하고자 합니다.
// pages/_middleware.ts
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return new Response('Hello, world!')
}
Middleware의 사용 방법은 Middleware를 적용하고자 하는 페이지에서 _middleware.ts
파일을 생성하고 적용하고자 하는 로직을 넣으면 됩니다.
Middleware가 들어오기 전에는 Next.js의 내장된 서버 대신 Express나 Nest.js를 사용하여 별도의 서버를 구성하거나, 혹은 별도의 서버에서 해야 될 작업 중 일부를 Api Routes와 getServerSideProps, Custom App 등을 사용하여 구현하곤 하였습니다.
물론 Middleware가 들어온 지금도 더 복잡한 로직을 사용해야 하는 경우에는 전자를, 그 이외의 상황에서도 일부는 후자에 기술된 내용들을 사용해야 하는 것은 변함이 없을 것 같습니다. 다만, 후자의 상황에서 일부 애매하게 사용하던 부분들을 해결할 수 있다는 생각이 듭니다.
- package.json
- /pages
- index.tsx
- _app.tsx # App getInitialProps
- _middleware.ts # root middleware
- /parent
- _middleware.ts # parent middleware
- /child
- _middleware.ts # child middleware
- index.tsx # child getServerSideProps
Middleware의 호출 순서를 확인하기 위하여 상단과 구조를 구성하고 _middleware
, Page.getServerSideProps
, App.getInitialProps
에 url 정보와 함께 로그를 남겨보았고 결과는 아래와 같았습니다.
root middleware /parent/child
parent middleware /parent/child
child middleware /parent/child
App getInitialProps /parent/child
child getServerSideProps /parent/child
root middleware /manifest.json
root middleware /images/favicon-32x32.png
root middleware
가 가장 먼저 호출되면 이어 parent middleware
, child middleware
순으로 호출되고, App의 getInitialProps
, child의 getServerSideProps
순으로 호출되는 것을 확인할 수 있었습니다. 페이지에 대한 호출이 완료되면 페이지에서 호출되는 자원들이 root middleware
를 호출하게 됩니다.
root middleware /parent/child
parent middleware /parent/child
child middleware /parent/child
App getInitialProps /_next/data/development/parent/child.json
child getServerSideProps /_next/data/development/parent/child.json
클라이언트에서 이동하게 될 경우에는 위와 같이 로그가 남았습니다.
middleware
가 App의 getInitialProps
보다 먼저 호출되기 때문에 서버에서 수행됐으면 하는 작업 중에, 전역에 적용하기에는 getInitialProps
는 클라이언트에 노출되고, 고차함수로 getServerSideProps
를 Wrapping하기 애매한 경우를 대치하기에 좋은 수단일 것 같습니다.
이 경우에 가장 먼저 떠오른 부분이 인증 관련 처리였습니다. 필자는 Template Library의 인증 부분에 적용하여 검증해보았고, 실무에서도 인증 로직을 middleware이 적용되어 사용해보고 있는데 기존에 사용하던 방식들에 비해 깔끔하고 확장하기도 용이해 잘 사용하고 있습니다.
middleware
에서 cookie
에 대한 read, write가 지원되고, redirect
와 rewrite
가 지원되어 인증 등의 작업에서는 아주 유용하게 사용하고 있습니다. 다만, 하나 아쉬운 부분은 middleware 체인 사이에 데이터를 넘겨줄 수 없어서, 체인 간 데이터를 전달해야 할 경우에는 대응할 수 없어 다소 아쉬웠습니다.