[error] 블로그 글 목록이 보이지 않아요!(w/ Vercel, Serverless)
블로그에 검색 기능을 추가한 이후 블로그 글 목록이 갑자기 보이지 않았습니다. 해당 문제를 해결하기 위해 접근한 방법과, 원인을 찾아가는 과정을 정리했습니다.
어제 저녁 블로그 탭에 검색기능을 만들고 잤습니다. 그런데 아침에 일어나니 배포된 사이트에서는 글 목록이 사라져 있었습니다. vs code를 켜서 열심히 진단을 해 보아도 겉보기엔 아무런 문제가 없어보였습니다. 오히려 dev 모드에서는 잘만 보이는데, 왜 배포된 사이트에서는 다른 결과가 나오는지 이해가 안됐습니다.
3시간에 걸쳐 에러를 해결한 방법과, 그 원인을 탐색한 과정을 정리해보려고 합니다.
1. 달라진 점은 하나 바로 SSR!
ninnipark.com/blog
로 접근을 하던, ninnipark.com/tags/[slug](태그 클릭시 나오는 페이지)
로 접근을 하던 블로그 글 목록이 없다고 뜹니다.
혹시나 싶어 ninnipark.com/blog/[글 제목]
으로 검색을 하니까, 또 신기하게 개별 포스팅은 잘 나오네요.
그렇다면 문제는 blog 리스트 페이지(/blog)와 tags 페이지(/tags)가 문제라는 뜻인데...
아무리 생각해도 달라진 것은 <Search />
컴포넌트를 추가했다 뿐인데 왜 이런 에러가 난 걸까요?
컴퓨터는 잘못이 없으니, 달라진 것은 저 뿐입니다. 그렇다면 제가 문제입니다.
그래서 찬찬히 생각을 해 보았습니다. 생각해보니 이번에 검색 기능을 추가하면서 달라진것은 또 있었습니다.
- 기존 블로그 리스트 페이지는는 SSG로 페이지를 서빙했지만, 검색결과 기능을 추가한 이후에는 dynamic route를 위해 SSR로 변경했다.
- 기존에 SSG로 빌드한 /blog와 /tags 페이지는 배포되었을 때 렌더링에 문제가 없었다.
- 즉 이 두 페이지들이 "dynamic"하게 바뀐 이후로 문제가 발생했다.
그렇게 생각을 하니 url을 통해 개별 포스팅에 접근했을 때 각 페이지에 제대로 접근이 가능했던 이유도 설명이 되었습니다.
블로그 포스팅들은 빌드타임에 정적으로 생성되어 있어도 상관 없기 때문에 SSG로 생성하도록 했기 때문에 이전처럼 문제가 없었습니다.
그렇담 일단 큰 원인 하나는 찾은 셈입니다.
의심 1: Dynamic Page Rendering이 원인 일 것이다.
그렇다면 의심을 확신으로 바꾸기 위해서는 다양한 추측을 통해 검증을 해야 합니다.
만약 검증을 통과한다면 더이상 의심이 아닌 명확한 원인이 될 것입니다.
2. 검증을 해봅시다. 어떻게?
일단 몇가지의 정황을 통해서 SSR이 문제라는 사실은 의심하고 있지만, 여전히 이 문제를 어떻게 검증해야할지 막막했습니다.
그래서 우선 yarn build
를 통해서 제가 만든 글 목록들이 제대로 build 되고 있는지 확인을 해보았습니다.
이제까지 제가 작성한 글들은 모두 잘 빌드가 되고 있었습니다.
빌드 타임에는 제가 작성한 글들이 모두 성공적으로 빌드 되는 것을 확인했으니, 남은 것은 런타임 문제 뿐이라는 생각이 들었습니다.
또한 검색기능을 추가한 이후로 블로그 글 목록이 서버에서 렌더링이 되기 때문에 런타임을 확인하는 것이 맞다고 생각했습니다.
그래서 다음으로는 포스팅을 렌더링 하기 위해 생성한 getPosts
함수를 확인 했습니다.
로그를 쉽게 보기 위해 console.warn
을 이용해서 해당 포스트들이 런타임에 잘 생성이 되는지 확인을 했습니다.
빈 배열의 등장.... 드디어 원인을 찾았습니다.
content
폴더에 생성한 mdx로 작성한 모든 포스트들을 불러오는 함수인 getPosts
에서 빈 배열이 반환되고 있었습니다.
이로써 의심 1 : Dynamic Page Rendering이 문제일 것이다.
라는 문제에는 어느정도 확신이 생겼습니다.
물론 그렇다고 해서 아직 이 문제를 완벽하게 해결할 수는 없습니다.
해당 함수가 왜 빈 배열을 반환하는지에 대한 원인을 찾아야 합니다.
posts자체가 빈 배열이라면, posts를 가져오는 방법이 잘못 되었다는 뜻이고... 그렇다면?
의심 2: 상대 경로가 문제일 것이다.
그렇다면 Vercel에서 제 프로젝트가 배포 되고, 실행되는 동안 어떠한 이유로 process가 working directory에서 상대경로로는 파일 시스템을
인식하지 못하는 것은 아닐까? 라는 두번째 의심이 들었습니다.
따라서 이를 테스트해보기 위해서
해당 코드를 절대경로로 수정했습니다.
그렇게 하자 드디어....! 제 글 목록들이 다시 화면에 렌더되는 것을 확인할 수 있었습니다.
의심 2: 상대경로가 문제일 것이다.
도 추측을 통해 확인을 했고, 드디어 글 목록도 다시 보임으로써 문제는 해결했습니다!
그러나 여전히 왜 상대 경로는 문제가 되는가에 대한 대답이 필요했습니다. 우선 대답을 찾기 전에 Vercel에서 runtime log또한 확인을 해보았는데요
런타임에는 경로가 /var/task/...
로 되어있는 것을 보아, 이전 코드에서 ./
로 시작하는 상대 경로가 원인일 것이라고 생각했습니다.
이를테면, 런타임동안 Server의 process가 모종의 이유로... 제 repository의 root directory를 인식 못한다..? 등등 여러 유추를 해보았는데요
따라서 이후 console을 통해 ./
가 가리키는 경로를 탐색해도 /var/task/
라고 로그가 찍히는 것을 보아 해당 가설은 폐기 되었습니다.
단순히 상대 경로가 문제였나..? 싶기도 했고
아무튼 이 궁금증을 해소하기 위해 vercel relative path 와 같은 키워드를 입력해가며 열심히 서칭해보았습니다.
결론 + 의심 3: Vercel에서 상대 경로를 인식하지 못하는 것이 문제일 것이다.(미해결)
따라서 이제 남은 것은 의심 3을 해결하는 것인데 사실 아직 명확한 이유는 모르겠습니다. 일단 여러 구글링을 통해 제가 유추한 원인은
- Vercel에서 해당 SSR 페이지들은 Serverless로 동작하기 때문에, 이에 실행시키는 함수와 관련 있을 것이다.
정도입니다.
또 서칭을 통해서
Next.js 공식 홈페이지
How can I use files in Vercel Functions?
도 참고해보았지만, 정확하게 왜 상대 경로는 안되는지 에 대한 이유는 찾을 수 없었고
Vercel에서 파일을 읽는 방법에 대해 제안하는 방법에 대해서만 찾을 수 있었습니다.
제가 Vercel의 Serverless나 다른 지식이 부족한 상태에서 더이상 혼자서 이럴 것이다..
라고 막연히 추측하는 것은 무의미하고.
추후에라도 더 공부해서 명확한 이유를 알게 된다면 따로 글을 작성하거나 해당 포스팅을 업데이트하도록 하겠습니다.