/JJ_WikiPage

Primary LanguageTypeScriptMIT LicenseMIT

JJ_WikiPage

사용자들이 누구나 접근하여 글을 작성하고 열람하고 글을 수정할 수 있는 게시판을 작성하였습니다.

배포 주소: https://jj-wiki-page.vercel.app/

해당 레포를 실행 할 때 yarn build 후 yarn start 하면 실행 됩니다.

메인 페이지

메인 페이지에서는 최대 5개의 글을 한번에 확인할 수 있으며 페이지네이션을 통해 최대 10개의 페이지를 한번에 이동할 수 있습니다.
만약 Next를 누른다면 다음 페이지부터 또 다시 10개의 페이지를 가져옵니다.
10개를 넘게 되면 Previous가 나오게 되며 이전 10개 페이지를 가져올 수 있습니다.


게시판의 글 제목 혹은 글 번호를 누르면 해당 페이지로 이동하게 됩니다.
글쓰기를 누르게 되면 글쓰기 페이지로 이동하게 됩니다.

글 작성 페이지

글 작성 페이지의 경우 마크다운 에디터를 활용하여 글 작성할 수 있도록 하였습니다. 제목과 함께 내용을 작성할 수 있습니다.

글 상세 페이지

"#"나 h1 태그를 작성한 경우 글의 타이틀로 인식하여 목차에 들어가게 됩니다.
목차에 있는 요소들은 클릭했을 때 해당 위치로 이동하게 됩니다.
수정 버튼을 누르면 해당 글을 수정 할 수 있습니다.
마크다운 형식을 지원하기 때문에 마크다운 문법을 사용한 여러 형태의 글을 작성하고 확인할 수 있습니다.
대표적으로 "#"을 이용한 제목이나 ">"을 이용한 인용문, `(백틱)을 이용한 코드 등을 활용할 수 있습니다.
마크 다운 형식을 지원하기 때문에 ()[]을 사용하면 다른 외부 혹은 내부의 글을 이동할 수 있습니다.

사용한 기술 스택

사용한 기술 스택은 아래와 같습니다.

  • Next.js
  • Tanstack-Query
  • Tailwind CSS
  • Shadcn-ui
  • React-Hook-Form
  • zod

각각의 사용한 이유는 다음과 같습니다.

  1. Next.js: SSR, SSG를 지원하기 때문에 SEO에 유리하며 사용자가 처음에 데이터를 받아올 때 미리 빌드된 HTML과 CSS를 받아오기 때문에 자바스크립트로만 받아오는 React에 비해 더 적은 용량의 데이터를 받아올 수 있습니다. 다만 HTML, CSS를 받아오는 만큼 모든 내용을 자바스크립트로만 처리하는 React와 다르게 화면이 깜빡일 수 있습니다.
  2. Tanstack-Query: 데이터를 페칭할 때 캐쉬를 이용하기 때문에 무분별한 Fetch를 줄일 수 있으며 원하는 타이밍에 refeching을 할 수 있기 때문에 서버의 상태 관리를 손쉽게 할 수 있습니다. 또한 Next.js의 SSR에 prefetch를 사용하여 대응할 수 있으며 React의 Suspense와 Error boundary를 사용하여 데이터를 페칭 할 때 다른 UI를 보여주거나 에러가 발생 했을 때 해당 컴포넌트만 다른 UI를 보여주는 기능을 활용할 수 있습니다.
  3. Tailwind CSS: 빌드할 때 CSS를 만들어주기 때문에 SSR 대응에 유리합니다. 따라서 Next.js와의 상성이 매우 좋습니다.
  4. Shadcn-ui: Tailwind CSS와 헤드리스인 Radix-ui 기반으로 만들어진 디자인 시스템 라이브러리 입니다. 빠른 디자인을 위해 사용하였으며 해당 디자인 컴포넌트만 다운 받아서 사용할 수 있기 때문에 가볍게 사용할 수 있습니다.
  5. React-Hook-Form: 처음 글과 내용을 작성할 때 폼으로 두개의 input 태그로 작성하였으며 여러번의 리렌더링을 막고 한번에 여러 input 태그를 관리하기 위해 사용하였습니다. 이후에 글 내용 부분에 더 많은 기능을 지원하기 위해 마크다운 에디터로 변경 하였지만 여전히 글 제목의 input 태그의 관리를 위해 남겨놓았습니다.
  6. zod: React-Hook-Form에서 Validation을 편하게 하기 위해 사용하였습니다. 주로 해당 값이 string인지 확인하기 위해 사용하였습니다. 에러 메시지를 커스텀 하기 위해 refine 함수를 사용하였습니다.

파일에 대해

/src/app

Next의 app router를 사용하기 때문에 /src에 app폴더를 넣었으며 app폴더에는 각각의 폴더에 (component)를 사용하여 해당 페이지에서만 사용하는 컴포넌트들을 넣었습니다.

/src/app/provider.tsx

해당 파일의 경우 Tanstack-Query 등 여러 외부 라이브러리의 Provider를 넣기 위해 별도로 만들어진 컴포넌트 입니다. RootLayout에서는 외부 라이브러리의 Provider를 넣을 수 없기 때문에 작성하였습니다.

/src/app/[detail]

글 상세보기를 뜯하는 detail 페이지의 경우 동적으로 관리되어야 하기 때문에 []를 사용하여 동적 라우팅을 하도록 하였습니다.

/src/api

글 작성과 수정, 목록 불러오는 간단한 기능을 위해 Next.js에서 지원하는 백엔드 api 기능을 이용하기 위해 api 폴더를 만들었습니다.
별도의 데이터베이스가 없기 때문에 api폴더에 더미데이터를 넣었으며 배열로 관리 하고 있습니다. 글을 작성하면 해당 배열에 글을 추가하고 수정 하도록 하였습니다.

/components

단 하나의 페이지에서만 사용하는 것이 아닌 여러 페이지에서 공용으로 사용되는 컴포넌트인 경우 /components에 넣어 사용하였습니다.

/hooks

여러 곳에서 반복적으로 사용하는 로직 들을 분리하여 사용하기 위해 만들었습니다. 해당 프로젝트에서는 글 상세보기 페이지와 수정 페이지에서 같은 로직이 있어서 혹으로 만들어 관리하도록 하였습니다.

/types

한곳이 아닌 여러 페이지에서 사용해야하는 타입들을 관리하기 위해 만들었습니다.

/utils

제작하면서 별도의 함수가 필요한 경우 혹은 라이브러리에서 필요한 코드가 있는 경우 utils로 빼냈습니다.
text에서 [[]] 형식으로 작성된 글을 링크로 변환 해주는 함수, 글의 타입을 체크 해주는 함수 등 여러 가지가 있습니다.

마크다운에 대해

처음에는 단순하게 글만 작성 되어있는 게시판을 생각하였습니다.
그렇기 때문에 본문에 있는 링크만 생각하여 어떻게 하면 string을 파싱하여 링크를 걸 수 있을까 고민했습니다.
그 결과가 utils에 있는 transformStringToLink.tsx입니다. string을 파싱하고 내용물 중 [[]]가 있다면 Next.js의 Link 태그로 변환해주는 함수입니다.
그러나 나무위키나 위키피디아를 살펴보고 더 많은 기능이 필요하다고 판단하여 마크다운 에디터를 넣었습니다.
마크다운 에디터로는 React-md-editor를 사용하였습니다. 사용한 이유는 제가 지난번 블로그를 작성할 때 한번 사용했던 경험이 있기 때문에 빠른 시간안에 개발하기 위해선 적합하다고 판단하였습니다.
또한 사용자의 수가 꽤나 있는 편이었으며 여전히 유지보수가 되고 있기 때문에 문제가 발생해도 해결할 수 있겠다는 생각이 들어 사용하였습니다.
경쟁군으로는 Toast-UI가 있었지만 생각보다 처음 사용할 때 로딩이 있는 편이었으며 간단하게 만들기에는 너무 무거웠습니다.
그리고 유지보수가 잘 되지 않았기 때문에 좋은 에디터지만 사용하지 않았습니다.