🔎 프로젝트 소개


노션 서비스와 유사한 기능을 구현한 프로젝트입니다.
부트캠프 과제를 발전시켜 TypeScript 기반의 SPA로 재구성했으며,
기존에 제공되던 API가 중단되는 이슈를 겪은 후, 직접 백엔드 서버를 NestJS로 구축하여 연결했습니다.
문서 목록 조회하기
- 사용자는 전체 문서를 조회할 수 있습니다.
- 하위문서를 열었다 닫을 수 있으며, 토글 여부는 저장됩니다.
문서 편집하기
- 사용자는 문서를 선택하여 편집할 수 있습니다.
- 다양한 서식을 지원하는 명령어를 입력하여, 원하는 방식으로 문서를 작성할 수 있습니다.
- 이모지를 선택하여 문서 제목에 원하는 이모지를 추가할 수 있습니다.
👩🏻💻 개발 내용
1. 문서 편집 에디터
- 작성과 동시에 서식 변환이 이루어지는 노션의 기능을 구현하였습니다.
contenteditable
속성을 활용하였으며, 아래와 같은 문제가 있었습니다.- Backspace 입력으로 블럭 삭제 시 해당 블럭 서식이 상위 블럭의 인라인 스타일(!important)로 강제 복사
- Enter 입력으로 블럭 추가 시 해당 블럭 서식이 마찬가지로 복사됨
- focus 시 가장 상위에 있는 element 에서만 이벤트가 발생함 ⇒ 현재 입력 중인 블럭을 알 수 없음
- 따라서 아래와 같은 방식으로 해결했습니다.
- Range 와 Selection 객체를 활용해 현재 커서가 위치한, 편집 중인 블럭을 추적하는 로직 구현
- Backspace / Enter 이벤트 발생 시의 블럭 삭제 및 추가 기능(줄 삭제, 줄 바꿈)을 직접 구현
- 추가적으로 아래와 같은 기능을 구현하였습니다.
/h1
,/h2
,/block
,###
등의 명령어를 입력하면 서식을 변환 (<h1>, <h2>, …)텍스트 선택 + 붙여넣기
시, 클립 보드 텍스트가 링크 형식일 경우 클릭 시 이동하는 <a> 태그로 변환
2. 중첩 가능한 SPA 라우터
- 재사용이 가능하고 렌더링 성능을 고려한 라우팅기능을 구현하고자 했습니다.
- route 이동 (navigate) 시 렌더링해야 하는 페이지들을 재귀적으로 탐색하고, 달라진 부분만을 렌더링하는 기능을 구현하여 성능을 개선했습니다.
3. 상태 관리 Store
- 컴포넌트 간 공유해야 하는 상태값들을 관리하는 스토어 클래스를 구현했습니다.
- 컴포넌트가 상태의 키 값을 subscribe 하면 업데이트 시 notify 해주는 방식으로 설계했습니다.
- 객체의 키 값을 순수하게 관리하기 위해 Symbol 타입을 활용했습니다.
- 연속적인 상태 변경이 발생할 시 비동기적으로 일괄 처리 (notify) 해주는 기능을 통해 성능을 개선했습니다.
4. 서버 요청 처리
- 요청해야 하는 api가 많아지거나, 메소드가 다양해질 경우의 유지보수를 위한 서버 요청 로직을 작성했습니다.
- ApiClient : axios/instance 기능을 참고하여, API 마다 인스턴스를 생성하여 활용할 수 있으며 HTTP 메소드에 맞게 내부 메소드를 호출하는 클래스
- makeRequest : 사이드 이펙트(onSuccess, onError, select 등)을 받아 데이터를 요청하고, 그에 따라 콜백 처리나 서버 데이터를 가공하는 등의 작업들을 실행하는 메소드
5. 이모지 추가 및 편집 기능
- emoji open api 를 사용하여, 카테고리 별로 이모지들을 불러오고 선택하는 기능을 구현하였습니다.
- makeRequest 메소드와 Store 클래스(위 참고)를 활용하여, 커서를 기반으로 동작하는 무한 스크롤 방식을 적용했습니다.
- 이모지를 제목과 함께 저장하고 표시하기 위해 서버로 보낼 때와 클라이언트에서 보여줄 때의 데이터 처리를 위한 유틸 함수를 구현했습니다.
- 세션 스토리지를 활용하여 최근 사용한 이모지를 저장하는 부가 기능을 추가했습니다.
6. NestJS + Vercel 기반 REST API 서버 구축 및 배포
- 기존에 사용하면 API 배포가 중단되면서, 서비스를 사용할 수 없는 문제가 발생하였습니다.
- 이를 해결하기 위해,
- NestJS 기반의 RESTful API 서버를 새롭게 구축하고, TypeORM을 사용하여 문서 모델 기반의 CRUD 기능을 구현했습니다.
- Supabase(PostgreSQL) 를 데이터베이스로 활용해 문서 데이터를 저장하고 관리할 수 있도록 설계했습니다.
- 서버는 Vercel Serverless Functions로 배포하였습니다.