개발 이야기/React & Next

[Next.js] 시작부터 원치않는 회귀(redirect)를 해버림(feat. 캐싱)

Heman 2024. 6. 2. 21:40

[Next.js] 시작부터 원치않는 회귀(redirect)를 해버림(feat. 캐싱)

오랜만에 글을 씁니다~
한동안 새로 알게된 내용이나, 트러블 슈팅 내용을 블로그에 기록하지 못했었는데요. 현재 개발하고 있는 내용들과 발생한 이슈들이 대부분 도메인과 밀접한 문제들이라 개인적인 기록을 하지 못했었네요 ㅎㅎ

하지만 이번 내용은 최근 새로 시작하게된 프로젝트의 환경세팅을 하다가 생긴 아주 따끈따끈한 일이랍니다!
 
 

새로운 프로젝트 (발단)

한동안(거의 10개월..) Vue 로 작성된 프로젝트를 개발(유지보수)하다보니 많이 어지러워진 저에게 오아시스 같은 새로운 프로젝트가 찾아왔습니다..!

설계는 커녕 기획도 아직 나오지 않은 제로부터 시작하는 프로젝트였고, 심지어 입사 후 3년만에 찾아온 첫 B2C 프로젝트라 기쁨(흥분)을 감출 수 없었습니다..!!
 
급한 마음에 담당 기획자 분께 구두로 어떤 요건들이 있는지 여쭤봤고, Next 14 그리고 React 18에서 지원하는 서버 컴포넌트를 사용해보기 아주 좋은 프로젝트라고 생각을 해버렸다~ 이말입니다..!!!
 
 

신나게 환경 세팅 해버리기 (전개)

신나버린 저는 이전부터 관심있게 보고있던 라이브러리들을 install 하고, 디렉토리 구조를 고민했습니다

중간에 다른 이야기이긴 하지만, 제로 런타임 스타일 라이브러리인 "Vanilla-Extract" 가 서버 컴포넌트와 궁합이 잘 맞을 것 같아서 적용해보았는데 어떨지 기대 중입니다 ㅋ
 
아무튼 프로젝트의 도메인이나 구조가 정해지지 않았지만, 우선 환경구축을 빠르게 진행하여 화면을 띄워야 했기에 구조 변경이나 확장성을 염두에 두고 기초 세팅을 진행하고자 했습니다.
 
 

Next.js redirect (위기)

웹 사이트들 중 간혹 루트 주소("/")에 접근하면 "/home" 이나 "/dashboard" 로 강제 리다이렉트 하는 곳들이 있지요.
Next js 에서도 여러 방법이 있지만, 시도해보지 않았던 컨피그를 이용한 리다이렉트 방법이 눈에 띄었습니다..!
 
아래 이미지와 같이 nextConfig 에 redirects() 메서드를 정의하면, 루트 "/" 경로로 들어올 때 항상 destination 인 "/home" 으로 리다이렉트를 해줍니다.
 

next.config.js 에 추가한 redirect 로직


이 방식을 단순히 그동안 시도해보지 않은 방법이라서 사용한 것은 아니고, 서버 컴포넌트에서는 hooks 를 사용할 수 없기 때문에 useEffect() 을 이용한 라이프사이클 단계에서 리다이렉트하는 방법은 바람직하지 않다고 생각했습니다 ㅎㅎ
 
저는 그렇게 만족스럽게 도커 빌드까지 테스트를 해보고 컨피그 파일과 테스트한 소스 파일들을 돌려 놓았는데요. 분명 소스를 되돌려 놓았음에도 루트 url 접근시 "/home" 으로 리다이렉트 되는 기괴한 장면을 보게 됩니다 ㄷㄷ
 
 

나 돌아갈래.. 아니 그만 돌아가 (절정)

사실 아직까지 당황하진 않았습니다. 아하 캐시가 남아 있구나~ 하면서 .next 파일을 날리고 프로젝트를 재 빌드했습니다.

(그런데 이제부터 당황함 ㅋ )
 
놀랍게도 아직 콘솔창에는 "/home" 을 컴파일하시겠다는 메세지가 떴고, 당연히 소스 파일에는 Home.tsx 컴포넌트를 되돌려 놓았으니 브라우저에서 404 페이지를 띄웠습니다.
 
어라..? next.config.js 가 저장이 안되었나..? 하고 파일을 보았지만 깔끔하게 아무 설정도 적용되지 않았는데요.
 
떨리고 있는 동공과 미간을 부여잡고 다시 한번 캐시를 지우고 브라우저에서 강력 새로고침(cmd + shift + R)을 눌렀습니다. 하지만 역시나 당당히 다시 "/home" 으로 리다이렉트 하려는 나의 프로젝트.. 굳건해 아주...
 
 

문제 해결 및 고찰 (결말)

결국 이 문제를 해결은 했는데요. 브라우저의 캐시를 완전히 날리고 나서야 온전히 돌아왔습니다.
대체 이런일이 왜 일어났는지 나름대로 공식 문서를 찾아보고 고민해보았습니다.
 

Next.js 기본 캐싱 동작 흐름

 
위 이미지는 Next.js 공식 문서에서 발췌한 기본 캐싱 동작 흐름입니다.

처음에는 도식의 가장 앞단인 CLIENT 단계에서 Router Cache 로 브라우저 메모리 어딘가에 저장하기 때문에 이런 일이 발생하는 것이라 생각했습니다.
 
하지만 기억을 되짚어보니 제 프로젝트는 빌드 된 이 후에 "/home" 으로 리다이렉트, 그 후에 404를 띄웠습니다.
 
또한 공식문서에서 Next.config.js 는 일반 Node.js 모듈이며, Next.js 서버 및 빌드 단계에서 사용된다고 나와있습니다. 그렇다면 도식을 기준으로 build time 이후에 캐싱이 되며, "/home" 페이지에서는 api request 를 요청하도록 작성하지 않았기 때문에 Full Route Cache 가 일어났거나 그 시점 부근에서 Next 내 다른 캐시 로직이 동작한 것으로 볼 수 있을 것 같습니다..!

( 엥 다른 캐시 로직? )

 
다른 캐시로직이 있을 가능성을 생각하는 이유가 한가지 있는데요.
공식문서의 Full Route Cache 설명을 보면, React Server Component Payload 와 HTML 을 캐싱한다고 합니다.

Full Route Cache 가 동작했다면 정적 페이지였던 "/home" 의 HTML 을 캐싱하고 있기 때문에, 404 를 띄우는 것이 아닌 화면에 "/home" 렌더링 결과를 띄웠어야합니다. 하지만 컨피그에서 지정한 경로만을 캐싱하고, HTML 은 캐싱하고 있지 않았으니 렌더링 할 결과물이 없어 404 로 리다이렉트 시켰다고 생각이듭니다.
 
그래서 저는 컨피그 파일을 캐싱하는 다른 어떤 로직이 있을 수 있다고 생각을 하였답니다..ㅎㅎ

그래서 공식 문서를 조금 더 찾아보았습니다.

제가 설정한 컨피그의 프로퍼티 중 permanent 라는 설정이 있습니다. 말그대로 영구적으로 리다이렉트 설정을 캐싱해두는 것일지도 모른다는 생각을 했는데요.

Next.js 공식문서 permanent 설명


위 이미지는 공식문서에서 발췌한 next config 에서의 redirect 설정 내용 중 permanent 옵션에 대한 설명입니다.

클라이언트/검색엔진에 영구적으로 리다이렉트 되도록 캐싱한다는 내용이었습니다. (충격)

저는 이렇게 범인을 찾아버렸고, 저의 삽질은 마무리가 되었답니다...
사실 공식문서를 꼼꼼히 읽지 않은 제가 범인ㅋ
 
 

마무리하며 

공식문서에서는 기본적으로 Next.js는 성능을 향상하고 비용을 줄이기 위해 가능한 한 많이 캐시를 활용한다고 설명합니다.

Next.js 의 컨피그 설정이 단순히 강력 새로고침으로 삭제할 수 없는 캐시 데이터를 남기는 것을 보고, 후에 조금이라도 변경 가능성이 있는 라우팅 설정은 컨피그에 남기지 않는 것이 좋다고 생각했습니다..
 
Next.js 강력한 기능들이 많은 동시에, 깊이 이해하기 쉽지 않군요ㅋㅋ
 
가능하면 next/navigation 의 redirect() 를 사용하세요 ㅎㅎ