favicon

Jayden { do: smite }

220922(목)

🪴 성장일지 2.0

행복한 이기주의자(웨인 다이어)의 내용에 자극받아 시작하는 소박한 성장기록

살아있는 꽃과 죽은 꽃은 어떻게 구별하는가?<br/> 성장하고 있는 것이 살아 있는 것이다.<br/> 생명의 유일한 증거는 성장이다!

🌳 키워드 (1.0) 최대한 간단하게 정리, 추후에 보면서 스스로 설명 🍉 경험 위주로 (2.0) 단순 정보를 전달하기보다 무엇을 배웠고 어떻게 해결했는지 짧고 간단하게 작성하자

Project get-shit-done

프로젝트한다고 바빠서 성장일지를 몇일 쓰질 못했다.<br/> 성장일지에서는 프로젝트를 하면서 배운 것들을 간단하게 남기고 따로 project 태그로 자세히 정리할 예정이다.

목표

  • 웹 컴포넌트를 통한 UI 구현

JavaScript 웹 컴포넌트

지난 몇 해 동안 수많은 자바스크립트 프레임워크(라이브러리)가 등장했다.(앵귤러, 뷰, 리액트 등등)<br/> 이런 프레임워크들은 다양한 문제를 편하게 해결할 수 있게 해주었지만, 덩치가 크기에 앱이 무거워지고 프레임워크에 종속된 코드를 생산하게 한다.<br/> 즉, 웹 컴포넌트는 이런 프레임워크도 좋지만 브라우저의 표준 기능을 이용해서 성능 좋은 앱을 만들자는 취지에서 시작한다.<br/> HTML, CSS, JS를 컴포넌트화하기 위한 4개의 표준을 묶어서 웹 컴포넌트라고 한다.<br/> 물론 이 4가지를 모두 동시에 써야만 하는 것이 아닌 원하는 기능만 사용하면 되고 프레임워크와 함께 사용해도 된다.<br/> 4가지 중 CustomElements와 ShadowDOM을 집중해서 살펴보자.

CustomElements

말 그대로, 내 마음대로 커스텀한 요소를 의미한다. <br/> 개인적으로 바로 코드를 보는 편이 이해가 빠르기에 아래 코드를 통해 정리한다.<br/>

// 아래와 같이 HTMLElement를 상속하는 개념으로 나만의 element의 클래스 객체를 만든다. // 참고로 class내의 this는 커스텀 엘리먼트 그 자체를 바인딩한다. class JaydenCustom extends HTMLElement { constructor() { super(); this.render(); } // 필수는 아니지만, render와 getTemplate 메서드를 통해 좀더 원하는 형태의 element를 만들 수 있다. render() { this.innerHTML = this.getTemplate(); } getTemplate() { return ` <div></div> <div></div> `; } /* connectedCallback: 커스텀 엘리먼트가 추가될 때, 호출된다. 주로 이곳에서 이벤트 핸들러를 다룬다. 여기서 주의할 점은 consructor에서는 이 요소가 `만들어질 때`이고 여기는 `추가될 때`라는 점이다. */ connectedCallback() {} // disconnectedCallback: 커스텀 엘리먼트가 제거될 때, 호출된다. 주로 위에서 생성한 이벤트 등의 정보를 지울 때 사용한다. disconnectedCallback() {} /* static get observedAttributes()에서는 `감시할 속성`을 알려주는 역할을 한다. [] 배열 형태로 속성을 전달한다. */ static get observedAttributes() { return []; } // 위에서 감시 대상이 된 속성의 값이 변경될 때마다 실행된다. attributeChangedCallback(name, oldValue, newValue) {} // 아무렇게나 원하는 메서드를 작성하여 활용할 수 있다. anything() {} } // 반드시 이렇게 커스텀 엘리먼트를 정의해주어야한다. // 또한, 커스텀 엘리먼트는 `aaa-bbb`와 같은 형식의 태그명을 갖도록 한다. customElements.define('jayden-custom', JaydenCustom);

ShadowDOM

브라우저의 렌더링 엔진은 html을 파싱하여 DOM을 형성한다. 이 때, 각 요소들은 노드로서 작용한다. 문제는 각 노드가 독럽적인 DOM 영역을 갖지 못하고 있다는 점이다.<br/> 이를 해결해주는 것이 Shadow DOM으로 말 그대로 보이지 않는 DOM을 만들어주어 각 요소가 독립적인 스타일링이 가능하게 해준다. 바로 코드를 보자.

class JaydenShadow extends HTMLElement { constructor() { super(); // this는 커스텀 엘리먼트를 바인딩, 즉 커스텀 엘리먼트에 shadow DOM을 붙여준다. this.attachShadow({ mode: 'open'); this.render(); } render() { // 아래와 같이 shadowDOM에 접근하기 위해서는 shadowRoot를 이용해야한다. this.shadowRoot.innerHTML = this.getTemplate(); } getTemplate() { return ` <style> div { background-color: tomato; } </style> <div></div> <div></div> `; } // 위에서 커스텀 엘리먼트 내부(정확히는 쉐도우돔)에 속한 div를 제외하고는 배경색(tomato) 값을 갖지 않는다. // 즉, 커스텀 엘리먼트만의 독자적인 공간을 만들 수 있는 것이다. connectedCallback() {} disconnectedCallback() {} static get observedAttributes() { return []; } attributeChangedCallback(name, oldValue, newValue) {} } customElements.define('jayden-shadow', JaydenShadow);

이외에도 Template Element와 HTML Import 등의 요소가 있지만, 위 2가지가 HTML, CSS, JS를 하나의 컴포넌트로 묶어주는 핵심 기능이지 않을까 생각한다.

undefined

Copyright 2023. all rights reserved by Jayden