티스토리 뷰

우테캠

우아한테크캠프 5주차 후기

안양사람 2021. 8. 7. 15:07
728x90
SMALL

 드디어 세번째 프로젝트가 끝났다. 이제 남은 프로젝트가 하나밖에 안남았다. 이럴수가... 뭔가 저번프로젝트에 비해 양이 적어서 시간이 남으면 뭘하지?? 라고 생각했었는데 새벽 3시반에야 간신히 끝냈다.... 이번 프로젝트는 진짜 구조를 짜는것과 리팩토링, 코드리뷰, 에러 처리 등에 많은 시간을 들였다. 굉장히 좋은 경험이라고 생각한다. 그런데 그러다보니 애니메이션이라던가 css 부분에 신경을 덜 쓴것같다. 우리팀은 피그마에 있는 내용을 바탕으로 만들었는데 다른팀은 애니메이션을 어마어마하게 적용했다. 우리팀은 진짜 기본적인 부분만 적용을 해서 차이가 느껴졌다. 그 중에 좀 과하다 싶은 것도 있었는데 일단은 사용하는 법을 알고 과한 것은 언제든지 줄일 수 있기 때문에 상관없다고 생각한다. 우리팀원과 나 전부 애니메이션 같은것을 제대로 해본적이 없다. 그래서 덜 적용한 것도 있다. 저번에는 팀원분이 css가 능숙한 분이여서 프로젝트 데모 직전에 전체적으로 손보니 훨씬 깔끔해졌는데 확실히 배울 필요성을 느낀다. 그리고 우아한 형제들에서는 퍼블리셔가 없는 팀도 있는만큼 css에대한 이해도를 중요하게 본다. 다른팀들을 보니 원래 css에 관심이 있는 분들이 많은 것 같다. 게다가 이번에는 svg나 canvas를 이용해서 차트를 그리는 부분이 있었는데 나는 svg circle만 알아봐서 다른 것도(path라던가) 공부해보고 싶다. 이번주는 우형의 프론트엔드 개발장인 김민태님 강의가 있었다. 우형에서는 풀스택 개발자를 원하고 추구한다고 하셨다. 나도 예전부터 프론트를 위주로 하지만 백엔드도 필요하다고 생각했는데 나의 가치관이 회사와 맞는 부분이 많은 것 같다. 결국 경력이 쌓여도 프론트쪽만 하게되면 생각이 갇혀있게 된다. 퍼블리셔가 있다고 해도 css에 대한 기본적인 이해(기본적이라는 건 레이아웃이 어색하지 않게 적용하고 애니메이션 svg 등도 적절하게 적용할 수 있는 정도)가 필요하고 reflow, repaint 개념을 생각하면 당연히 css도 개입이 될 수 밖에 없다. 나는 비전공자의 cs지식에 대한 질문을 했다. 김민태님이 질문여러개를 묶어서 비슷하게 바꿔서 원래 질문과는 조금 달라지기 했지만 결론은 꾸준히 해야된다 였다. 자신도 꾸준히는 못해도 한번씩 잡아서 그런 공부를 하고 서점에서 관심있는 책이 있으면 샀다가 한번씩 본다고 했다. 그리고 우형에서 원하는 개발자가 무엇인가 라는 질문이 있었는데 거의 정석과도 같은 대답이였다. 프론트, 백엔드, cs에 대한 전반적인 지식을 본다고 했다. 물론 주니어인만큼 높은 수준을 바라는 것은 아니라고 했지만 음... 좀 어렵네... 당연히 수요가 있는 회사다 보니 어쩔 수 없다고 생각한다. 그리고 프로젝트를 봤는데 프론트엔드 개발자의 특징을 볼 수 없다고 했다. 프론트엔드 개발자의 특징이 css말고 뭐가 있을까... jest같은 라이브러리를 사용한 테스트?? 렌더링방식을 이용한 dom 조작? 잘 모르겠다. 코드의 질이나 버그가 없는 것도 중요하지만 결국엔 눈에 보이는게 우선인가? 라는 생각이 들었다. 하지만 css를 1순위로 보지는 않는다. 기본은 자바스크립트에 대한 이해와 dom에 대한 이해라고 나는 생각한다. 근데 이게 진짜 좀 어렵다. 나뿐만 아니라 대부분이 동의할거라고 생각한다. dom조작이나 리랜더링 방식을 라이브러리나 프레임워크 없이 조작해보면 진짜. 찐짜..진짜 어렵다. 크롱님은 어차피 실패하는게 당연하다고 했다. 리액트와 virtual dom의 대단함을 다시 한번 느낄 수 있었다. 우리팀은 이번주에 갑작스럽게 렌더링 동작을 바꿨다. 팀원분이 가져온 구조로 조금 수정했는데 이때 range라는 객체를 처음 알았다. 코드는 아래와 같다.

class View {
  $target: HTMLElement;
  state: object;
  constructor({ $target }) {
    this.$target = $target;
  }
  get html() {
    return this.$target;
  }
  render() {
    this.$target.innerHTML = this.markup();
  }

  update() {
    const newMarkup = this.markup();

    const newDom = document.createRange().createContextualFragment(newMarkup);

    const newElements = Array.from(newDom.querySelectorAll('*'));
    const currentElements = Array.from(this.$target.querySelectorAll('*'));

    if (newElements.length !== currentElements.length) {
      this.$target.innerHTML = newMarkup;
      return;
    }

    for (let i = 0; i < newElements.length; i++) {
      const newEl = newElements[i];
      const curEl = currentElements[i];

      if (newEl.childElementCount !== curEl.childElementCount) {
        this.$target.innerHTML = newMarkup;
        return;
      }

      if (!newEl.isEqualNode(curEl)) {
        if (newEl.tagName !== curEl.tagName) {
          curEl.replaceWith(newEl);
        } else {
          if (
            curEl.firstChild?.nodeName === '#text' &&
            curEl.firstChild.nodeValue !== newEl.firstChild.nodeValue
          ) {
            curEl.firstChild.nodeValue = newEl.firstChild.nodeValue;
          }

          const curAttributes = curEl.attributes;
          const newAttributes = newEl.attributes;

          Array.from(curAttributes).forEach((attr) => {
            if (!newAttributes.getNamedItem(attr.name))
              curEl.removeAttribute(attr.name);
          });

          Array.from(newAttributes).forEach((attr) => {
            const currentAttribute = curAttributes.getNamedItem(attr.name);
            if (!currentAttribute || currentAttribute.value !== attr.value)
              curEl.setAttribute(attr.name, attr.value);
          });
        }
      }
    }

    newElements.forEach((newEl, i) => {});
  }

  markup() {
    return '';
  }

  setState(nextState) {
    this.state = nextState;
    this.update();
  }

  getGlobalState() {}
}
export default View;

 

 

쉽게 말해서 const newDom = document.createRange().createContextualFragment(newMarkup); 이 코드로 fragment에 dom을 붙이는 것이다. 참고로 newmarkup은 string으로 되어 있다. ( ex) '<div>안녕</div>')

이렇게 해서 이전 노드들과 새로운 노드를 비교하고 바뀌는 부분만 바꿔주는 것이다. 그런데 노드의 개수가 다를때는 방법을 찾지못했다. 다른경우에는 attribute나 textnode, class등을 비교해서 바꿔줬다. 잘 생각해보면 이 방법으로도  리렌더를 적용할 수 있다고 생각한다. virtual dom처럼 따로 파싱하지 않아도 말이다. 

 여기서 range를 너무 모르고 사용하는 것 같아서 이것을 주제로 발표하기로 마음먹었다. 그런데 생각과는 조금 다르게 쓰이고 있었다. 이렇게 fragment를 만들수도 있지만 보통은 selection과 같이 사용되는 경우가 많았다. 이것을 이용해서 게시판 에디터를 만든다고 한다. 자세한 설명은 하지 않고 영상과 참고자료를 첨부한다.

 

https://www.youtube.com/watch?v=smV4W4OJRD0&ab_channel=%EC%9C%A4%EC%9C%A4 

 

https://javascript.info/selection-range 

 

Selection and Range

 

javascript.info

 

아래는 프로젝트 입니다.

 

 

https://github.com/woowa-techcamp-2021/cashbook-03

 

GitHub - woowa-techcamp-2021/cashbook-03: 우아한 테크캠프 4-5주차 가계부 서비스 - 윤민상, 전상인

우아한 테크캠프 4-5주차 가계부 서비스 - 윤민상, 전상인. Contribute to woowa-techcamp-2021/cashbook-03 development by creating an account on GitHub.

github.com

 

http://ec2-52-78-160-142.ap-northeast-2.compute.amazonaws.com/

 

우아한 가계부

 

ec2-52-78-160-142.ap-northeast-2.compute.amazonaws.com

 

https://www.youtube.com/watch?v=McrdrI2Hll0&ab_channel=%EC%9C%A4%EC%9C%A4 

 

728x90
LIST

'우테캠' 카테고리의 다른 글

우아한테크캠프 8주차 후기  (0) 2021.08.28
우아한테크캠프 6주차 후기  (0) 2021.08.14
우아한테크캠프 4주차 후기  (0) 2021.07.31
개발시 필요한 함수들  (0) 2021.07.24
우아한테크캠프 3주차 후기  (0) 2021.07.24
댓글
공지사항