6월 27일 부터 7월 6일까지 노션 클로닝 프로젝트을 진행했습니다. 자주 쓰이는 회고 방법론인 KPT회고를 이용해서 이번 프로젝트 회고를 진행하려 합니다.
0.KPT
KPT회고는 프로젝트에서 좋았던 점을 Keep(유지)하고 Problen(문제)를 명확히 정의하고, 이를 바탕으로 Try(시도)할 것들을 정리하는 회고 방법입니다.
keep: 잘하고 있는 점, 계속 했으면 좋겠다 싶은 점
problem: 문제라고 생각하는 점, 변화가 필요한 점
try: 잘하고 있는 것을 더 잘하기 위해, 문제가 있는 점을 해결하기 위해서 우리가 시도해 볼 것들
1. 프로젝트
📌 요구사항
✏️ 기본 요구사항
- 기본적인 레이아웃은 노션과 같으며, 스타일링, 컬러값 등은 원하는대로 커스텀합니다.
- 글 단위를 Document라고 합니다. Document는 Document 여러개를 포함할 수 있습니다.
- 화면 좌측에 Root Documents를 불러오는 API를 통해 루트 Documents를 렌더링합니다.
- Root Document를 클릭하면 오른쪽 편집기 영역에 해당 Document의 Content를 렌더링합니다.
- 해당 Root Document에 하위 Document가 있는 경우, 해당 Document 아래에 트리 형태로 렌더링 합니다.
- Document Tree에서 각 Document 우측에는 + 버튼이 있습니다. 해당 버튼을 클릭하면, 클릭한 Document의 하위 Document로 새 Document를 생성하고 편집화면으로 넘깁니다.
- 편집기에는 기본적으로 저장 버튼이 없습니다. Document Save API를 이용해 지속적으로 서버에 저장되도록 합니다.
- History API를 이용해 SPA 형태로 만듭니다.
- 루트 URL 접속 시엔 별다른 편집기 선택이 안 된 상태입니다.
- /documents/{documentId} 로 접속시, 해당 Document 의 content를 불러와 편집기에 로딩합니다.
✨ 보너스 요구사항
- 기본적으로 편집기는 textarea 기반으로 단순한 텍스트 편집기로 시작하되, 여력이 되면 div와 contentEditable을 조합해서 좀 더 Rich한 에디터를 만들어봅니다.
- 편집기 최하단에는 현재 편집 중인 Document의 하위 Document 링크를 렌더링하도록 추가합니다.
- 편집기 내에서 다른 Document name을 적은 경우, 자동으로 해당 Document의 편집 페이지로 이동하는 링크를 거는 기능을 추가합니다.
- 그외 개선하거나 구현했으면 좋겠다는 부분이 있으면 적극적으로 구현해봅니다!
💻 결과

배포 링크
클래스 설명
사용법 및 데모
아래 요구사항을 제외하곤 모두 구현했습니다
편집기 내에서 다른 Document name을 적은 경우, 자동으로 해당 Document의 편집 페이지로 이동하는 링크를 거는 기능을 추가합니다.
디렉토리 구조


2. KPT
2-1. Keep
일정관리
- 기능별로 마일스톤을 정해 일정을 관리했습니다.
- 그 결과 마감 기한 3일전에 기본 기능 구현 및 배포를 끝낼 수 있었고 추가 기능을 더 개발 할 수 있었습니다.
PostCSS도입
- 리액트처럼 Styled Component로 관리할 수 없기 때문에 PostCSS를 이용해 컴포넌트마다 스타일을 관리했습니다.
- 이에 따라 CSS를 더 편하게 수정 및 추가할 수 있었습니다.
새로운 디자인 패턴 시도
- 여러가지 디자인 패턴들을 사용하려 했습니다.
- 데이터의 흐름을 쉽게 알 수 있도록 Flux패턴, 클래스를 생성할때 의존성을 줄이기 위해 Factory패턴을 도입했습니다

재미있게 개발 하기
-
프론트엔드 개발을 시작할 때 재밌기 때문에 시작했고 과제로 힘든 와중에도 재미를 잃기 싫었습니다.
-
이번 프로젝트에서도 중간중간 힘들때마다 프로젝트에 흥미를 잃지 않도록 일정이 허락하는 안에서 추가 기능들을 개발했습니다.
-
라우터 문제로 고생할 때는 Homepage나 NotFound페이지 레이아웃들을 디자인하고 UI를 구현했습니다.
Not Found

-
게시글 페이지에서 리치한 에디터를 만들기 위해 고생할 때 게시글 생성, 수정, 삭제가 일어났음을 알려주는 모달 창을 만들었습니다.
-
기본 요구사항에는 없는 일이었지만 재미있게 개발하기 위해, 나중에 서비스를 사용할 사용자를 위해 추가적인 개발을 진행했습니다.
UX에 대한 고민
- 게시글이 추가, 저장, 삭제된다는 사실을 사용자에게 알려주고 싶어 알림 모달을 만들었습니다.
- 사용자에게 브레드 크럼과 세부 리스트를 보여줌으로써 현재 위치를 쉽게 알 수 있게 했습니다
알림 모달

브레드크럼과 세부리스트

문서화
- github wiki를 작성해보았습니다.
- 프로젝트의 규모와 기간이 길어져 완벽하게 작성 하지는 못했지만 매일매일 트러블 슈팅과 개발일지를 작성했습니다.
- MerMaid Editor를 이용해 class Diagram을 작성해 클래스 간의 관계를 쉽게 알 수 있도록 했습니다.
2-2. Problem
-
테스트 코드 부재
- 사실 이 문제가 크게 대두되지는 않았지만 프로젝트가 커짐에 따라 가장 큰 문제점이 될 수 있다고 생각합니다.
- 기능 개발하기 벅차 어느 순간부터 테스트 코드 작성을 포기했습니다.
- 그로 인해 디버깅에 많은 시간을 쏟게 되었고 개발을 마친 후에도 버그 없이 잘 돌아가는 코드라는 확신을 가질 수 없었습니다.
-
Netlify에 배포했을 때 SPA 관련 버그
- Netlify에 Vite를 배포할때 새로고침(Refresh)시 Page Not Found 에러가 발생했습니다.
-
리치한 에디터의 focus 관리와 같은 버그들
- textArea에서 contenteditable한 div로 변경하는 과정에서 저장할때마다 포커스가 맨 앞으로 이동하는 버그
-
content에 여러 스타일을 적용했을 때의 문제
- content에 스타일을 적용 및 해제할 때 selection과 range api를 이용해 해당 스타일이 적용됐는지 확인한후
- 스타일이 적용되지 않았다면 style이 적용된 span으로 감싸주고 적용됐다면 span을 해제했습니다
- 이렇게 하니 스타일을 설정한 순서대로 해제해야 하는 불편함이 있었습니다
- ex) bold -> italic순으로 스타일을 설정했다면 italic -> bold 순으로 스타일을 해제해야 정상적으로 해제
-
하위 게시글로 라우팅 됐을 때 토글이 닫혀 있는 문제
- 사이드바는 초기에 하위게시글을 보여주는 드롭다운을 안보이도록 설정했습니다.
- 게시글 페이지로 이동할 때마다 sidebar를 리렌더링하도록 했습니다
- 만약 이동한 게시글이 어떤 게시글의 하위 게시글인 경우 드롭다운이 닫혀있기 때문에 상위 게시글들의 드롭다운을 열어가면 찾아야 했습니다.
2-3. Try
-
테스트 코드 부재
- 8월에 jest과 테스팅에 대해 좀 더 공부할 계획입니다.
-
Netlify에 배포했을 때 SPA 관련 버그
-
리치한 에디터의 focus 관리와 같은 버그들
textArea에서 contenteditable한 div로 변경하는 과정에서 저장할때마다 포커스가 맨 앞으로 이동하는 버그
- 게시글 수정 이벤트가 일어날때마다 커서를 div의 마지막으로 이동하게 했습니다.
- 이렇게 하니 제목을 수정한 후에도 content에 해당하는 div의 마지막으로 커서가 이동했습니다.
- 멘토님께도 여쭤봤지만 vanilla에서는 해결하기 어렵다는 답변을 받았습니다... ㅠ
-
content에 스타일 적용 및 해제할 때 문제
- 초기 로직:
- 선택된 범위가 해당하는 스타일이 설정된 span으로 덮여있는지 검사
- 해당 조건에 해당하면 span 제거 해당하지 않으면 span으로 감싸기
- 변경 로직:
- 선택된 범위가 span으로 덮여있는지 검사
- span으로 덮여있지 않다면 스타일이 적용된 span으로 감싸기
- span으로 감싸져 있고 해당하는 스타일로 설정 안돼있다면 스타일 추가
- span으로 감싸져 있고 해당하는 스타일이 설정 됐다면 span 에서 스타일 제거 -> span에 모든 스타일이 제거 됐으면 span 삭제
-
하위 게시글로 라우팅 됐을 때 토글이 닫혀 있는 문제
- sidebar 렌더링 할때 현재 문서와 일치하는 문서 item을 찾고 반복문을 이용해 모든 드롭다운 부모들을 찾아 올라가며 드롭다운 open
3. 소감
노션 클로닝 프로젝트를 하면서 Vanilla JS를 딥하게 할 수 있어서 좋았습니다.
옵저버패턴을 적용해서 구현했기 때문에 기본 기능 구현 후 추가 기능을 구현할 때도 수월하게 개발 할 수 있었습니다.
디자인 패턴을 적용하는 이유는 유지보수에 유리한 코드를 만들기 위함임을 느낄 수 있었습니다.
상태관리도구와 SPA 라이브러리, 프레임워크를 본격적으로 학습 하기 전 원리를 조금이나마 이해할 수 있어서 좋았습니다.
마지막으로 다른 수강생들이 결과물을 사용해보고 잘 만들었다고 칭찬해줬을 때 가장 뿌듯했습니다 😄 소심한 관종
PS. 컴포넌트가 Store에 의존성을 가지는 문제를 해결하기 위한 고민을 하고 있었는데 1기 종현님이 React Redux의 connect함수에 대해 알려주셨습니다. 고민할 주제를 알려주셔서 감사합니다 :)