면접경험을 통해 내가 만든 프로젝트에 대해서 잘 정리해야 할 필요성을 느꼈습니다.
하루쓰기란 프로젝트에서 어떤 기술 스택을 사용하였고, 특정 기술을 활용해서 어떠한 이점을 얻었는지, 프로젝트에서 아쉬운 점은 무엇이 있는지 되돌아보고자 이 포스트를 쓰게 되었습니다.
하루쓰기란 기획부터 유지보수까지 모두 직접 개발한 일기 웹 서비스입니다. 그리고 api방식을 통해 회원과 일기를 CRUD하고, 좋아요, 신고하기, 회원 검색하기 등의 기능을 갖춘 웹서비스입니다. 이 웹서비스를 만들기까지 어떤 프레임워크와 라이브러리를 이용하였는지 설명드리겠습니다.
Next.js는 SSR(서버-사이드 랜더링)과 CSR(클라이언트-사이드 랜더링)의 기능을 모두 제공하는 리엑트 프레임워크입니다.
기존 React는 CSR으로 서버에서 전달받은 HTML 정보를 받은 이후에 클라이언트 측에서 JavaScript와 같은 스크립트 언어를 실행하는 시간만큼 화면에 보여지지 않는 문제가 있습니다. 만약 랜더링할 파일에서 JavaScript의 역할이 굉장히 많아 동작 시간이 길어진다면 그만큼 딜레이가 발생할 수 있습니다.
하지만 SSR의 기능을 통해 서버에서 미리 JavaScript를 실행한 완성된 HTML파일을 제공합니다. 클라이언트의 브라우저에서 JavaScript를 실행하는 시간만큼 단축시킨 경험을 제공할 수 있습니다.
과거에는 대부분의 검색엔진 사이트 검색로봇이 JavaScript를 수집하지않고 HTML의 주요 영역을 수집하여 검색엔진에 노출시켰습니다. 그렇기 때문에 SSR를 통해 자바스크립트가 실행되어 완성된 HTML의 정보를 받았을때 더 정확한 정보를 제공하여 SEO측면에서 이점이 있었습니다. 하지만 최근에는 다양한 웹 서비스의 검색로봇이 자바스크립트를 수집하고 콘텐츠를 해석하고 있습니다.
그렇다고 해서 CRS가 단점만 있는 것은 아닙니다.
페이지 일부만 변경한다고 했을 때, (해당 페이지에 대한 모든 정보를 다시 가져올 필요없이) 서버에서 필요한 데이터만 호출하면되기 때문에 클라이언트인 브라우져에서 동작하여 빠르게 렌더링할 수 있습니다.
SSR, CSR의 단점을 서로 보완하고 장점을 살려 웹 페이지를 생성할 수 있다는 점이 제가 Next.js를 사용한 가장 큰 이유입니다.
Next.js는 Vercel를 통해 지속적인 유지보수할 수 있습니다. Vercel은 호스팅뿐만 아니라 빌드, 배포, DB연동, 사용자 분석까지 다양한 기능을 제공하고 있습니다. DB서버를 직접 구축할 필요없이, Vercel에서 제공하는 postgres 서버리스 서비스를 이용하여 간단한 모델링과 SQL작업 만으로 api를 구현할 수 있습니다. 자신의 프로젝트를 Vercel을 연동시키면, 새로운 작업을 추가할 때마다 빌드 시 에러가 발생하는지 확인하고, 배포하게 됩니다. 뿐만 아니라 사용자의 http 요청과 응답에 대한 Log도 확인할 수 있기 때문에, http 요청사항에 대한 문제 파악도 수월하게 확인할 수 있습니다.
@Next/Image와 @Next/Font를 이용하여 다양한 콘텐츠의 리소스를 최적화시킬 수 있습니다. Next.js의 설정파일인 nextConfig 부분에서 image의 format을 설정할 수 있습니다. Next.js에선 최신 이미지 형식인 .avif
와.webp
를 지원합니다. 이미지의 용량을 줄이고, 이미지의 크기를 자동으로 설정하여 이용자가 CLS(Cumulative Layout Shift, 예기치 못한 레이아웃 변화)의 경험을 최소화시킵니다. @Next/Font에서는 프로젝트에서 설정한 폰트가 적용되기 이전의 기본 폰트(Flash of Unstyled text, FOUT)와 같은 크기의 폰트를 제공하여 주변 레이아웃에 영향을 주지 않습니다. 이러한 경험은 웹 성능에 영향을 미칩니다. 따라서, Next.js를 이용하면, 웹 성능 개선에 크게 도움이 됩니다.
React는 가상돔을 이용하여 바닐라JS의 DOM조작보다 신속하게 대응할 수 있습니다. (물론, 조작해야 할 DOM 노드가 많은 복잡한 웹사이트일수록 효과가 큽니다. 돔 조작이 적은 정적 웹사이트일수록 오히려 React를 사용하지 않은 경우가 좋을 수 있습니다. 리엑트가 무조건적으로 좋은 건 아닙니다.)
React는 가상돔 개념을 통해 빠르게 DOM조작을 돕는다. 가상돔이란 DOM의 복사본으로, 자바스크립트 객체 형태로 메모리에 저장하고 있습니다. 리엑트는 가상돔 2개를 가지고 있습니다. 하나는 변경사항이 있는 가상돔이고, 다른 하나는 변경이전의 가상돔입니다. 리엑트는 이 둘을 비교하여 변경된 노드들을 찾는 바뀐 부분들만 한번에 변경해줍니다. 여기서 바뀐 노드들을 '한번에' 변경하는 리엑트의 가상돔 변경과정을 통해, 기존 DOM조작으로 여러 변경사항을 하나하나 변경하는 과정보다 효율적으로 변경해줄 수 있습니다.
리엑트는 state와 props를 기반으로 컴포넌트를 구현합니다. 해당 컴포넌트에서 사용하는 데이터를 state로 표현하고, 큰 컴포넌트 안에 사용된 작은 컴포넌트의 state를 props를 통해 전달할 수 있습니다. 이러한 방식으로 리엑트는 작고 독립적인 컴포넌트들을 조합하여 거대한 컴포넌트를 구현할 수 있습니다. 필요한 상황에 따라 원하는 컴포넌트들만 가져다 조합하여 만드는 방식이기 때문에 모든 코드를 수정할 필요가 없습니다. 컴포넌트 단위로 수정한다거나 혹은 새로운 컴포넌트를 만들어 필요에 따라 확장할 수 있는 OCP(Open-Closed principle, 변경에는 닫혀있고, 확장에는 열려있는 원칙) 구조의 아키텍쳐를 구현할 수 있습니다. 그렇기 때문에 리엑트를 사용하면, 프로젝트를 유지보수하기에 용이한 아키텍쳐 환경을 제공할 수 있습니다.
또한 하나의 컴포넌트를 여러 곳에서 사용이 가능합니다. 만약 같은 코드를 반복하여 작성된 부분이 있다면, 하나의 컴포넌트로 분리한 뒤, 이를 가져다 쓸 수 있습니다. 따라서 리엑트는 재사용성이 뛰어난 아키텍쳐입니다.
next-auth는 세션 관리를 자동으로 처리합니다. 사용자가 로그인하면 세션이 생성되고, 사용자가 로그아웃하거나 세션이 만료되면 세션이 자동으로 삭제됩니다. 이를 통해 사용자 인증 상태를 쉽게 관리할 수 있습니다.
next-auth는 보안을 중요하게 고려하여 설계되었습니다. 기본적으로 CSRF 보호, 세션 토큰 암호화, JWT 서명 등을 포함한 다양한 보안 기능을 제공합니다. 이를 위한 미들웨어기능도 제공하며, 이를 통해 애플리케이션의 보안을 강화할 수 있습니다.
next-auth는 클라이언트와 서버 모두에서 인증 상태를 쉽게 관리할 수 있습니다. 서버 사이드 렌더링(SSR)을 지원하여, 페이지 로딩 시 인증 상태를 확인하고, 인증된 사용자에게만 특정 페이지를 보여줄 수 있습니다.
Google, Facebook, Twitter, GitHub, LinkedIn 뿐만 아니라 우리나라의 Naver, kakao 다양한 OAuth 제공자를 지원합니다.
next-auth는 Next.js와의 완벽한 통합을 목표로 설계되었습니다. Next.js의 API Routes와 잘 맞물려 작동하며, Next.js의 페이지 컴포넌트에서 인증 상태를 쉽게 확인하고 활용할 수 있습니다. Next.js를 사용하고 있고, SNS계정 인증이 필요한데, 서버를 특별하게 구현할 일이 없다면 next-auth를 쓰지 않을 이유가 없을 겁니다.
저는 다음과 같은 이유로 하루쓰기 프로젝트에서 해당 기술스택을 채택하게 되었습니다. 혹시 저의 프로젝트에 관심이 있으시다면, 한번 놀러와주세요! 감사합니다!
하루쓰기 깃허브 링크: https://github.com/KANGPUNGYUN/harudiary