동의를 많이 구하지 못할 주장일 수 있으나, 개인적으로는 확신이 없다면 프로젝트의 초기 기술 스택을 Next.js로 정하지 않아야 한다고 생각합니다.
글은 아래 순서로 전개될 예정입니다.
모든 어플리케이션은 시간이 지나며 성장하고 변화합니다. 유저 수가 많아지고, 기능이 추가/제거되고, 버그를 수정하고 사용성을 개선하며 어플리케이션의 정체성이 확실해지며 앞으로 어떤 방향으로 나아가게 될지 가닥이 조금씩 잡힙니다.
다시 말해, 프로젝트를 시작할 때 우리는 어떤 버그가 생길지 / 코드가 어떻게 설계될지 / 어떤 기능이 추가될지 / 어떤 방향으로 나아가게 될지 알 수 없습니다.
Next.js
자체는 매우 좋은 프레임워크입니다. Next.js 를 사용한다면 대부분의 구성이 가능합니다. 하지만 그럼에도 Next.js 를 써서 어플리케이션을 구성한다면, 이 어플리케이션의 개발자는 매우 높은 확률로 Next.js 와 싸우게 됩니다.
가령 Next.js
는 많은 버그가 있는 프레임워크입니다. 제공해주는 기능이 워낙 많다 보니 어쩔 수 없어 보이기도 하지만, 가령 페이지 이동 시 css override 가 꼬여서 스타일이 날라가는 치명적인 버그도 종종 발생합니다. 개발자는 이런 버그와 싸워야 합니다.
또한 Next.js
의 기능을 활용하다 보면 많은 것이 제한됩니다. 가령 pages router
에서는 shallow routing
을 통해 상태를 url query param 에 저장해두고 이를 통해 부드러운 상태 전환이 일어나면서도 새로고침 시 상태가 유지되도록 하는 것이 가능했으나, 2023년 4월 기준 app router
를 이용하다 보면 쿼리파람을 변경하면 무조건 서버컴포넌트부터 다시 돌아야 했습니다. 이 때문에 상태 전환이 매우 느렸고, 개발자는 원하는 기능을 개발하기 위해 다른 방법을 찾아야 합니다. 결국 2023년 11월에 window.pushState
API를 활용하여 이를 구현할 수 있도록 지원되었으나 이는 이슈가 제보된 지 7개월이나 지난 시점이었습니다.
이 외에도 많은 예시들이 있고 Next.js 를 써 보신 분들이라면 Next.js 와 싸우게 된다는 데에 공감하실 것입니다.
그리고 이렇게 싸우게 되었을 때 우리는 Next.js 말고 다른 프레임워크를 사용했어야 했다는 후회를 종종 하게 됩니다.
Next.js 를 사용한다면, 당연하게 pages router 라면 getServerSideProps
를 통한 데이터 페칭을, app router 라면 server component
를 통한 데이터 페칭을 구현하게 됩니다. 또한 강제적으로 라우팅은 file system
을 기반으로 하게 됩니다. 이는 너무나도 당연하며, 이 기능들을 활용하지 않는 것은 불가능할 뿐더러 이용하지 않는다면 Next.js 를 이용할 이유가 하나도 없습니다.
하지만 이들은 매우 Next.js 종속적인 기능입니다. 한번 이런 기능들을 사용했다면 다른 프레임워크로 마이그레이션하는 것은 매우 어렵고 부담스럽습니다. 코드를 제거하고 변경하는 식의 마이그레이션을 해야 하기 때문입니다. 서버 컴포넌트에서 데이터 페칭하던 것을, Create React App
프레임워크로 마이그레이션하면서 모두 @tanstack/react-query
에서 페칭하도록 변경해야 한다고 생각해 볼까요? 최소 몇천 줄을 수정해야 할 것이고 이는 프로젝트의 안정성에 큰 영향을 미칩니다.
"모든 프레임워크가 그렇지 않냐?" 라고 생각할 수 있지만, 그렇지 않습니다. 가령 vite
를 이용해서 react typescript SPA 환경을 구성했다면, 이를 Next.js 로 마이그레이션하는 것은 점진적인 도입이 가능하고 심지어 마이그레이션 가이드까지 존재합니다. 반면 migrating from next
라는 가이드는 거의 존재하지 않는데, 사실상 불가능하기 때문입니다.
1~3번을 종합해 보겠습니다. Next.js 는 분명 많은 문제를 해결해주는 편리한 프레임워크이지만,
따라서 확신 없이 프로젝트의 초기 기술 스택을 섣불리 Next.js
로 결정한다면, 꽤나 높은 확률로 우리는 Next.js와 싸울 것이고 오버스펙을 선정한 것에 대한 후회를 하게 될 것입니다.
개인적인 추천은 보통 vite
라고 불리며 현재 시점 기준으로 React SPA 환경을 구성할 때 대표주자인 vite react-ts template
과 react-router
조합입니다. 이 조합은 vite
를 활용하기에 빠르고 확장 가능한 설계를 갖추고 있습니다. SPA는 지난 2010년대 내내 이용된 형태이기에 대부분의 써드파티 서비스 등이 최소한 SPA는 지원합니다.
결정적으로 이 템플릿은 다른 메타프레임워크로 마이그레이션하기가 쉬운데, Next.js, Remix, Gatsby 등 다양한 메타프레임워크들이 React Single Page App 에서의 마이그레이션을 문서화하여 지원하고 있습니다. 이 템플릿이 메타프레임워크가 아니고 강제성이 낮기에 다른 메타프레임워크로의 마이그레이션이 "할 만 한 수준" 이기 때문입니다.
앞서 Next.js 를 초기 스택으로 결정하지 않아야 한다는 말에 계속 확신 없이
라는 조건을 붙였는데요, 확신이 있다면 Next.js
를 초기 스택으로 선정하는 것도 괜찮습니다.
가령
vite
로 시작하더라도 추후 Next.js로 마이그레이션해야 할 것이 너무나도 뻔하다거나등등의 상황이라면 Next.js 를 초기 스택으로 결정하는 것도 물론 합리적입니다.
좋은 포스팅 잘 보고 갑니다 :) 최근 NextJS 를 공부하고 있었는데 포스팅 덕분에 시야가 넓어진 것 같습니다.