[프로젝트 회고] Notion Cloning Project

임지선·2023년 7월 17일

프로젝트 개요

  • 프로젝트 주제 : 업무 관리 툴 Notion 클로닝

  • 프로젝트 일정 : 6월 27일(화) ~ 7월 6일(목)

  • 프로젝트 요구사항 :

    바닐라 JS만을 이용해 노션을 클로닝합니다.
    기본적인 레이아웃은 노션과 같으며, 스타일링, 컬러값 등은 원하는대로 커스텀합니다.
    글 단위를 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의 편집 페이지로 이동하는 링크를 거는 기능을 추가합니다.
    그외 개선하거나 구현했으면 좋겠다는 부분이 있으면 적극적으로 구현해봅니다!

프로젝트 결과물

ezgif com-video-to-gif (1)

프로젝트 과정

  • Document는 Document 여러 개를 포함할 수 있다.

    << 구현 방법 아이디어 >>

    1. Document 트리를 만들어야 겠다.
    2. 각각의 Document들이 parent를 갖고 있어서 parent가 null이라면 그 Document가 root가 된다.
    3. 데이터는 api를 통해서 가져오고, 화면에 보여줄 때 트리의 깊이를 알아야 한다.
// 화면에 Document 목록을 보여주기 - Document : 트리 구조
this.makeList = ($wrap, data) => {
	data.forEach(({ title, documents, id }) => {
    	const { $postItemBox, $postSubItemBox } = PostItem(title, id);

     	$wrap.appendChild($postItemBox);

      	if (documents.length > 0) {
        	this.makeList($postSubItemBox, documents);
      	}
	});
};
  • Document Tree에서 각 Document 우측에는 + 버튼을 클릭하면, 클릭한 Document의 하위 Document로 새 Document를 생성하고 편집화면으로 이동한다.

    << 구현 방법 아이디어 >>

    1. post method 이용한다.
    2. parent는 className을 이용한다.
    3. 화면 이동은 router를 이용한다.
// 새로운 하위 문서 생성 버튼 이벤트 처리
$addButton.addEventListener("click", async () => {
    const createdPost = await request("/documents", {
    	method: "POST",
    	body: JSON.stringify({
        title: "제목 없음",
        parent: $addButton.className,
    	}),
	});
	pushRouter(`/${createdPost.id}`);
});
  • 따로 저장 버튼을 만들지 않고, Document Save API를 이용해 지속적으로 서버에 저장되도록 한다.

    << 구현 방법 아이디어 >>

    1. 일정 시간 간격을 두고 자동적으로 저장되도록 설정한다.
    2. 저장 방법은 put method를 이용해 서버와 통신한다.
// 2초 간격으로 put method api 호출
onEditing: (post) => {
	if (timer !== null) {
    	clearTimeout(timer);
  	}

  	timer = setTimeout(async () => {
    	if (this.state.postId) {
      		await request(`/documents/${this.state.postId}`, {
        		method: "PUT",
        		body: JSON.stringify(post),
      			});
      		pushRouter(`/${this.state.postId}`);
      		await getDocument();
    	}
  		}, 2000);
	},
});

후기

이번 노션 클로닝 개인 프로젝트를 하면서 에러도 많이 만나고, 의도하던대로 작동하지 않아 삽질도 많이 했었다. 결국 제출 마감일까지 해결하지 못해 그 상태로 제출했지만, 코드 리뷰를 받으면서 원인을 분석해 해결해 나아가고 싶다.

  • 해결하지 못한 문제
    • Document Tree SPA 구조 : 코드 리뷰 결과 다른 방식으로 구현했다고 해 요청사항 미수행
    • Document 목록과 편집 페이지가 좌우 반전되는 rendering 문제 : 문제 원인 appendChild로 추측
    • 디자인 : hover, focus 등 css 디자인 더 신경쓰기
    • 불필요한 데이터 state 관리 부분 및 api 호출 등 자잘한 코드 리팩토링 필요
  • 보완해야 할 점
    • 위의 해결하지 못한 문제들 해결하기
    • Document 하위 경로 표시하기
    • Document 하위 경로 클릭 시 해당 Document로 바로가기 기능 추가하기
    • 추가 기능들 구현해 rich한 에디터 만들기
profile
성장하는 프론트엔드 개발자입니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

뛰어난 글이네요, 감사합니다.

답글 달기