
개발자 지석호의 포트폴리오 및 블로그 웹 서비스입니다.
SEOKO는 개발자 지석호의 포트폴리오 및 블로그 기능을 포함한 웹 서비스입니다. 저의 경험과 공부한 내용을 정리하여 기록하고 성장하는 과정을 보여드리기 위해 개발하였습니다. 이 서비스는 지속적으로 리팩토링하면서 꾸준히 개발할 예정입니다.
LANGUAGEtypescript@^5.0.4: Typescript를 사용하여 타입 안정성을 확보하고 코드 가독성을 높입니다.FRONT-ENDnext@13.4.19: Next.js를 사용하여 서버사이드 렌더링 및 정적 사이트 생성을 구현합니다. app router를 사용하여 페이지 라우팅을 구성합니다.@tanstack/react-query@^4.29.19: 데이터를 관리하고 캐싱을 사용하여 API 요청을 최적화합니다. data hydration을 통해 server-side에서 pre-fetching을 구현합니다.axios@^1.4.0: API 요청을 보내기 위해 axios를 사용합니다. interceptor를 사용하여 인증 여부를 확인합니다.tailwindcss@^3.0.7: Tailwind CSS를 사용하여 스타일을 구성합니다. 기존 emotion을 사용하여 스타일링을 구현하였으나 css-in-js가 server component에서 동작하지 않아 변경하였습니다. css variable과 tailwind theme를 매칭하여 light/dark mode를 구현합니다.BACK-END@nestjs/cli@^10.0.0: NestJS를 사용하여 서버를 구성합니다. repository pattern을 통해 model과 service의 결합도를 낮추고 유지보수성을 높입니다.@nestjs/jwt@^10.1.0: JWT를 사용하여 access token과 refresh token을 발급합니다. 해당 token을 통해 사용자 인증을 구현합니다.mongoose@^7.3.4: MongoDB ODM 라이브러리인 Mongoose를 사용하여 data object와 DB schema를 매핑합니다.pm2@^5.3.0: 무중단 배포를 위해 pm2를 사용합니다. docker container에서 실행되는 app의 상태를 관리합니다.DEVOPSMongoDB: MongoDB를 사용하여 데이터베이스를 구축합니다. 스키마를 정의하고 Replica Set을 구성하여 transaction을 지원합니다.docker: Docker를 사용하여 컨테이너화된 서비스를 구축합니다. Dockerfile과 docker-compose를 사용하여 개발 환경과 배포 환경을 구성합니다.github actions: Github Actions를 사용하여 CI/CD 파이프라인을 구축합니다. PR이 올라올 때마다 빌드 및 테스트를 진행하고 배포를 진행합니다.nhn cloud: NHN Cloud를 사용하여 서버 인스턴스를 생성하고 도메인을 연결합니다. nginx를 사용하여 reverse proxy를 구성하고 letsencrypt를 사용하여 SSL 인증서를 발급하여 https를 적용합니다.
architecture.png
Infinite Scroll무한 스크롤을 적용하여 사용자 경험을 향상시킵니다. Intersection Observer API를 사용하여 마지막 요소가 감지되면 다음 페이지의 게시글을 불러옵니다.
Dark Mode
Tailwind CSS의 dark mode를 사용하여 다크 모드를 구현합니다. 사용자가 토글 버튼을 클릭하여 다크 모드로 전환할 수 있습니다.Markdown - Editor@uiw/react-md-editor를 사용하여 마크다운 에디터를 구현했습니다. 기존 라이브러리에서 제공하는 image 업로드 기능에 문제가 있어 직접 커스텀하여 이미지 업로드 기능을 구현했습니다.1const imageHandler = async (e: React.ChangeEvent<HTMLInputElement>) => {
2 const file = e.target.files?.[0];
3
4 if (!file) return;
5
6 const encodedFile = new File([file], encodeURI(file.name), { type: file.type });
7
8 const formData = new FormData();
9
10 formData.append("image", encodedFile);
11
12 const imageUrl = await mutateAsync(formData);
13
14 // 이미지 업로드 후 에디터에 이미지 추가
15 const textarea = document.querySelector(".w-md-editor-text-input") as HTMLTextAreaElement;
16
17 const api = new commands.TextAreaTextApi(textarea);
18
19 const modifyText = `\n`;
20
21 api.replaceSelection(modifyText);
22};
Markdown - Viewer
react-markdown를 사용하여 구현하였으나 해당 라이브러리는 빌드시 용량이 크고 compile 시간이 오래 걸려 markdown-to-jsx로 변경하였습니다. 내장 기능을 사용하여 커스텀 컴포넌트를 mdx 형식으로 적용할 수 있도록 구현하였으며 code highlight, table of contents등을 구현하였습니다.Main Page
main
간단한 소개와 최신순 게시글 목록을 확인할 수 있습니다.
게시글 목록을 클릭하여 상세 페이지로 이동할 수 있으며 태그를 클릭하여 해당 태그를 가진 게시글 목록을 확인할 수 있습니다.
검색창을 통해 제목, 내용과 매칭되는 게시글을 검색할 수 있습니다. 디바운스를 적용하여 API 요청을 최적화하였습니다.
또한 무한 스크롤을 적용하여 페이지 네이션을 구현하였습니다.
Series Page
series/detail
작성된 게시글을 시리즈로 묶어서 관리할 수 있습니다. 해당 시리즈를 클릭하여 시리즈에 속한 게시글 목록을 확인할 수 있습니다.
시리즈 상세 페이지에서는 시리즈에 속한 게시글 목록을 확인할 수 있습니다. 상단 버튼을 통해 오름차순, 내림차순으로 정렬할 수 있습니다.
이전 게시글 목록 컴포넌트를 재사용하여 무한 스크롤을 적용하였습니다.
Project Page
project/detail
프로젝트 목록을 확인할 수 있습니다. 각 년도별로 정리되어 있으며 프로젝트를 클릭하여 상세 페이지로 이동할 수 있습니다.
About Page
about
지석호라는 개발자에 대한 소개와 정보를 확인할 수 있습니다. skill, experience, project를 확인할 수 있으며 skill과 experience는 로그인 후 수정할 수 있습니다.
Write Page
post/project
해당 페이지에 경우 post/project 모두 동일한 에디터를 사용하며 markdown을 사용하여 작성할 수 있습니다. 이미지 업로드 기능을 구현하였으며 이미지를 업로드하면 해당 이미지를 에디터에 추가할 수 있습니다.
Post Detail Page
좌측 좋아요/중앙 마크다운/우측 TOC
게시글의 상세 내용을 확인할 수 있습니다. 좌측에서는 toggle 버튼을 통해 좋아요를 누를 수 있습니다. 우측에서는 TOC를 확인할 수 있으며 클릭시 해당 위치로 이동합니다. 최하단으로 이동하면 댓글을 작성할 수 있습니다.