항해99 플러스 프론트엔드 2주차 프레임워크 없이 SPA 만들기

손유민·2025년 3월 17일

항해99 플러스 프론트엔드 2주차

항해 모든 일정이 끝나고도 너무 바쁜 시간이다.. 뒤늦게 회고를 진행하는 것에 반성하고있다.


프레임워크 없이 SPA 만들기

이번 2주차 과제는 저번 1주차 과제에 이어서 진행이 되었다.
1주차에서 직접 라우팅을 구현을 했었는데, 2주차는 VNode을 직접 만드는 것 부터 시작이다.

2주차 발제 주요 목표

  • 기본 과제
    • createVNode, normalizeVNode, createElement, eventManager, renderElement 함수 작성
    • 테스트 코드 통과 시키기
    • 과제 제출 전 모든 테스트 통과 확인

  • 심화 과제
    • Virtual DOM의 diffing 알고리즘 구현
    • 이벤트 위임 방식으로 개선
    • 테스트 코드 통과 시키기
    • 과제 제출 전 모든 테스트 통과 확인


2주차 과제 전까진 VNode가 뭔지 몰랐다
GPT에게 물어보니

from ChatGPT

VNODE는 **Virtual Node(가상 노드)**의 약자로, 
가상 DOM(Virtual DOM) 구현의 핵심 개념 중 하나입니다. 
가상 DOM은 주로 React, Vue, Svelte와 같은 프레임워크에서
UI 업데이트를 효율적으로 처리하기 위해 사용됩니다.

당시 리액트 작성이 처음이여서 과제 목표부터 설정하고 실행했었다.


문제 상황 / 해결


createVNode 함수 테스트가 계속 실패하는 상황

  • createVNode

    export function createVNode(type, props, ...children) {
      return {
        type,
        props,
        children: children
          .flat(Infinity)
          .filter(
            (child) => child !== false && child !== null && child !== undefined,
          ),
      };
    }

    처음엔 위처럼 작성 했는데, 이상하게 테스트 코드에서 평탄화 문제가 계속 생겼다.
    export function createVNode(type, props, ...children) {
      children = children.flat(Infinity).filter(
        (child) => child !== false && child !== null && child !== undefined,
      );
    
      return { type, props, children };
    }

위 함수 createVNode는 가상 노드를 생성하는 역할을 하는 함수다.
주어진 태그(typs), 속성(props), 그리고 자식 요소(children)를 기반으로 객체를 반환하는 간단한 가상돔 생성 함수이다.

처음 작성한 createVNode 함수는 children을 변형하지 않고 return 시점에서 flat(Infinity)filter()를 적용하는 반면, 수정한 코드에서는 children을 먼저 가공한 후 변경된 값을 그대로 return 객체에 사용하는 차이가 있다.

첫번째 코드는 .flat(Infinity)children에 바로 적용하기 때문에 createVNode(...)로 생성된 VNode 객체까지 평탄화 될 수 있다.
VNode들이 평탄화 되면서 개별적인 VNode 객체가 아닌 일반 객체처럼 처리될 위험이 있다.
그래서 테스트가 계속 실패했었다..

수정한 코드는 children을 먼저 변환한 후 return하기 때문에 VNode 객체가 배열에서 분리되지 않고 유지된다.
변형이 함수 호출 시점에서 일어나니 VNode 객체는 그대로 children배열 내 요소로 유지될 수 있으니 중첩된 구조를 유지하면서 불필요한 값들을 필터링 할 수 있는 방식으로 동작한다.

놀랍게도 이 문제를 해결 못해 미루고 미루다 과제 제출 마지막날 해결했다.

이번 과제는 쉽지는 않았지만 나머지 코드를 작성하며 생겼던 오류들이 createVNode 함수를 수정하고 모두 정상화 되었었다.


과제 셀프 회고

기술적 성장

프레임워크 없이 SPA 만들기 과제에 VirtualDOM 위주의 내용이였지만 테스트 코드에 맞춰서 기능을 개발해보는 좋은 경험이었다.
나중에 TDD 주차에 매운맛이 훅 오겠지만 이번주차에 미리 맛을 본 것 같았다.
웹디자인, 퍼블리싱 업무만 보다가 테스트 코드 VirtualDOM 내용이 던져지니 2주차부터 고비가 오기는 했다.
그래도 주어진 방대한 양의 발제자료와 팀원 분들의 도움으로 JavaScript 지식도 점점 쌓여가는걸 느끼고있다.

새로운 지식의 발견

  • 가상돔(VirtualDOM) : 메모리상 존재하는 DOM의 복사본으로 상태 변경 시 새로운 VirtualDOM 트리를 생성하고 이전 트리와 비교해 변경사항만 실제 DOM에 적용하여 조작을 최소화.
  • 버블링 : 이벤트가 가장 하위 요소에서 시작해 상위로 전파
  • 캡처링 : 이벤트가 최상위 요소에서 시작해 하위로 전파
  • 이벤트 위임 : 여러 이벤트를 관리할 때 각 요소에 리스너를 추가하는 대신 공통된 조상 요소에 하나의 리스너를 추가하는 기법
  • 디바운싱 : 연속적으로 발생하는 이벤트를 그룹화하여 마지막 이벤트만 처리하는 기법 (입력 필드의 자동완성, 검색 기능 등 사용)
  • 쓰로틀링 : 일정 시간 간격으로 이벤트 처리를 제한하는 기법 (스크롤 이벤트 처리, 리사이즈 이벤트 처리 등 사용)
profile
프론트가 되고싶은 웹디자이너

0개의 댓글