GDSC ys 프론트엔드 스프린트: Dom visualizer 개발 후기

old_dorim·2022년 11월 12일
0

즐거운 개발 후기

목록 보기
1/2
post-thumbnail

Dom visualizer

프론트엔드 스터디 스프린트

Google Developer Student Club에서 프론트엔트 파트 관련 스터디를 진행하고 있다. 4개의 프로젝트를 받아서 2주씩 진행을 한다. 첫번째 스프린트인 dom visualizer가 끝나서 후기를 작성하려고한다.

1. dom-visualizer
2. npm 패키지 배포
3. electron 비즈니스툴
4. graphic 프로젝트

명세

주제가 모 기업 인턴 과제라는 소문이 있었다. html 코드를 받아서 dom 트리 모양으로 랜더하면 된다.

  • html 인풋창
  • html 파싱 기능
  • 잘못된 DOM 입력 시 에러 처리-간단하게 사유를 표시
    1) 제대로 닫히지 않은 태그 <>\</>
    2) 깊이가 잘못된 태그 <div><span><div/></span>
    3) 속성값이 쌍따옴표/따옴표로 잘 감싸져 있는지 data-attr=“’, data-attr=“
    4) 빈 값이 할당된 속성 data-attr=””
    5) 태그 내 중복된 속성 값
    6) script, style 태그는 무시하지만, (1)(2) 에러 처리에는 포함
  • 돔 트리 이미지 랜더
  • 태그(element)/속성(attribute)/텍스트(text)끼리 시각적으로 구분 가능

나는 명세만 딱 맞췄다. 지금 코드에서 주석 태그 처리가 별로 어렵진 않은데 하진 않았다.

기간

3주를 받긴 했는데 실제 작업 시간은 3-4일 정도...

기술 스택

TypeScript를 요구해서 TypeScript를 사용했고... devDependency말고 없다.

과정&코드

세팅

module

html에 js를 module로 가져왔더니 html에서 js를 호출하지 못하고 js만으로 html을 건드려야 했는데, 리액트가 왜 그런 구조인지 조금 더 이해가 된 듯...

브라우저는 common.js를 지원하지 않는다. ESmodule도 SOP(single origin policy) 등으로 돌릴 때마다 터지거나 모듈 위치 못 찾거나 그랬다.

TypeScript


예전에 JavaScript 코드에 TypeScript를 씌운 적이 있는데 그 때는 그냥 막힐 때마다 any를 사용했는데, 처음부터 아예 TypeScript로 작성하니까 느낌이 달랐다.

any를 한 번 할당했는데 가슴이 찢어진다...

TypeScript를 얹는 게 확실히 낫다!는 건 모르겠는데(여전히 NaN이 나를 괴롭혔다) null이나 undefined, 코드 구조, JavaScript의 타입 관련해서 조금 더 신경 쓰게 됐다.

학교에서 배운 객체 지향 한 번 더 익힌 거 같기도 하다.

rollup

rollup를 번들링에 사용했다. rollup은 npm 패키지 배포할 때 rollup을 썼더니 익숙해져서 관성으로 그냥 사용했다.

코드

작업 순서도 아래와 같은 순서로... 차례로... Parser는 금방 끝났는데 Tokenizer와 Renderer가 오래 걸렸다...

Tokenizer

  • input-날 것의 html string
  • output-태그 이름, 태그 종류, 속성 등을 가지는 Token 객체.

여기를 또 3부분으로 쪼갰다.

태그/텍스트로 일단 구분하는 기능,
태그 내에서 tagname text와 attribute text를 구분하는 부분,
attribute를 객체로 키/값으로 구분하는 부분.

여는 태그, 닫는 태그, 텍스트를 준다.
여는 태그 중 여기서 혼자 닫히는 태그(meta, link, img, br)등에게 따로 번호를 준다.

tagname, attribute 둘 다 문제가 있을 때는 에러 키와 에러 이유를 넣어서 파서에 일단 넘겼다.

Parser

  • input-태그 이름, 태그 종류, 속성 등을 가지는 Token 객체.
  • output-dom tree 객체의 root node, 최대 레벨과 레벨 별 노드 개수

stack으로 열린 태그는 push, 닫힌 태그는 top과 같을 때 pop하면서 Token을 상속해 부모/자식 속성과 level을 추가한 Node 객체를 만든다.

여기서 stack에 넣느라 순회하는 김에 여기서 error 태그를 체크해서 에러를 리턴했다. Html 구조가 잘 닫혔는지도 여기서 체크한다.

node마다 레벨이 어디인지 체크해서 넣어주고, 한 레벨에 최대 몇 노드가 들어가는지 체크하여 배열로 만든다. 랜더러에 넘겨서 랜더에 사용할 것이다.

Renderer

  • input-dom tree 객체의 root node, 최대 레벨과 레벨 별 노드 개수
  • output-html 화면에 돔트리 랜더

트리를 재귀로 순회하면서 attribute도 레벨 별 카운트에 넣어준다. 현재 레벨의 다음 레벨 노드 개수와 합친다. 이렇게 레벨이 몇 개인지, 한 레벨에 몇 노드가 들어가는지 파악해서 각 노드의 좌표를 잡아준다. 부모가 100 100이라고 치고 퍼센트로 잡는다. 나름 반응형인...ㅎㅎ

좌표와 속성을 받아 화면에 Node 이미지를 만드는 함수, 부모 노드 좌표와 내 좌표를 받아 줄을 그어주는 함수를 만들었다.

renderingLine 함수가 부모 노드 좌표와 내 좌표를 기준으로 div를 만들고 clip-path로 선을 만들었다. %로 뒀더니 div 크기에 따라 선 굵기가 달라진다ㅠㅠ


그래서 사실 선마다 div가 깔려있다.

다시 순회하면서 render해준다. error 어트리뷰트는 빨갛게 랜더하고 왜 에러가 났는지 이유를 띄워준다.

결과

https://mumwa.github.io/dom-visualizer/
https://github.com/mumwa/dom-visualizer

아쉬운 점& 앞으로 고치고 싶은 점

  • KMP 같은 문자열 비교 관련 알고리즘을 몰라서 공부하고 적용할 수 있으면 하고 싶다.

  • 그래픽 라이브러리 안 쓰고 선을 긋거나 하는데 한계가 있었다. 어차피 좌표를 다 구했으니까 쓰면 훨씬 나은 모양으로 만들 수 있을 것 같다.

  • 내가 임의로 넣은 self-closing같은 속성들을 랜더에서는 쳐내기

  • 주석 처리를 넣고 싶다.

나중에 고치면 알려드리겠습니다.

디자인이나 구성 자체는 마음에 듭니다.
튜닝의 끝은 순정이다!

profile
미래엔 햄스터를 다운 받을 수 있겠지? 설치류니까...

0개의 댓글

관련 채용 정보