Google Developer Student Club에서 프론트엔트 파트 관련 스터디를 진행하고 있다. 4개의 프로젝트를 받아서 2주씩 진행을 한다. 첫번째 스프린트인 dom visualizer가 끝나서 후기를 작성하려고한다.
1. dom-visualizer
2. npm 패키지 배포
3. electron 비즈니스툴
4. graphic 프로젝트
주제가 모 기업 인턴 과제라는 소문이 있었다. html 코드를 받아서 dom 트리 모양으로 랜더하면 된다.
나는 명세만 딱 맞췄다. 지금 코드에서 주석 태그 처리가 별로 어렵진 않은데 하진 않았다.
3주를 받긴 했는데 실제 작업 시간은 3-4일 정도...
TypeScript를 요구해서 TypeScript를 사용했고... devDependency말고 없다.
html에 js를 module로 가져왔더니 html에서 js를 호출하지 못하고 js만으로 html을 건드려야 했는데, 리액트가 왜 그런 구조인지 조금 더 이해가 된 듯...
브라우저는 common.js를 지원하지 않는다. ESmodule도 SOP(single origin policy) 등으로 돌릴 때마다 터지거나 모듈 위치 못 찾거나 그랬다.
예전에 JavaScript 코드에 TypeScript를 씌운 적이 있는데 그 때는 그냥 막힐 때마다 any를 사용했는데, 처음부터 아예 TypeScript로 작성하니까 느낌이 달랐다.
any를 한 번 할당했는데 가슴이 찢어진다...
TypeScript를 얹는 게 확실히 낫다!는 건 모르겠는데(여전히 NaN이 나를 괴롭혔다) null이나 undefined, 코드 구조, JavaScript의 타입 관련해서 조금 더 신경 쓰게 됐다.
학교에서 배운 객체 지향 한 번 더 익힌 거 같기도 하다.
rollup를 번들링에 사용했다. rollup은 npm 패키지 배포할 때 rollup을 썼더니 익숙해져서 관성으로 그냥 사용했다.
작업 순서도 아래와 같은 순서로... 차례로... Parser는 금방 끝났는데 Tokenizer와 Renderer가 오래 걸렸다...
여기를 또 3부분으로 쪼갰다.
태그/텍스트로 일단 구분하는 기능,
태그 내에서 tagname text와 attribute text를 구분하는 부분,
attribute를 객체로 키/값으로 구분하는 부분.
여는 태그, 닫는 태그, 텍스트를 준다.
여는 태그 중 여기서 혼자 닫히는 태그(meta, link, img, br)등에게 따로 번호를 준다.
tagname, attribute 둘 다 문제가 있을 때는 에러 키와 에러 이유를 넣어서 파서에 일단 넘겼다.
stack으로 열린 태그는 push, 닫힌 태그는 top과 같을 때 pop하면서 Token을 상속해 부모/자식 속성과 level을 추가한 Node 객체를 만든다.
여기서 stack에 넣느라 순회하는 김에 여기서 error 태그를 체크해서 에러를 리턴했다. Html 구조가 잘 닫혔는지도 여기서 체크한다.
node마다 레벨이 어디인지 체크해서 넣어주고, 한 레벨에 최대 몇 노드가 들어가는지 체크하여 배열로 만든다. 랜더러에 넘겨서 랜더에 사용할 것이다.
트리를 재귀로 순회하면서 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같은 속성들을 랜더에서는 쳐내기
주석 처리를 넣고 싶다.
나중에 고치면 알려드리겠습니다.
디자인이나 구성 자체는 마음에 듭니다.
튜닝의 끝은 순정이다!