Front End분야에서 Component 기반으로 설계하고 구현하는 방식의 개발 사이클로 많이 사용 되고 있다. 그리고 그런 개발 사이클의 유통에 React, Svelte, Vue 등의 UI Framework or Library가 상당한 기여를 하고 있는 점은 부정할 수 없다.
그렇다면 이런 UI Framework or Library를 사용하지 않는다면 Component 기반으로 설계하고 개발할 방법이 없는걸까?
이런 물음에 대한 답으로 Web Components가 등장한다.
Front End 개발을 시작하는 개발자 들은 UI Framework등을 사용하여 개발 하기 때문에 웹 컴포넌트를 다뤄볼 일이 많지는 않을 것이다. 하지만 웹 컴포넌트는 HTML5 표준 스팩으로 모든 DOM기능을 갖춘 사용자 Element를 구현하도록 해준다.
웹 컴포넌트는 Can I use를 확인해 보면 알 수 있듯 대부분의 브라우저에서 지원하는 기술로 다음과 같이 설명 가능하다.
기능을 캡슐화 하여 재사용 가능한 커스텀 엘리먼트를 생성하는 다양한 기술들의 모임
웹 컴포넌트는 구현에 일반 적인 순서는 아래와 같다.
<template>
, <slot>
을 사용해 템플릿 정의하고 정의한 템플릿을 클론하여 shadow DOM에 추가위 순서대로
tag를 상속하는 custom element를 만들어 본다 하면 아래 코드와 같을 것 이다.
// Create a class for the element
class WordCount extends HTMLParagraphElement {
constructor() {
// Always call super first in constructor
super();
// count words in element's parent element
const wcParent = this.parentNode;
function countWords(node){
const text = node.innerText || node.textContent;
return text.trim().split(/\s+/g).filter(a => a.trim().length > 0).length;
}
const count = `Words: ${countWords(wcParent)}`;
// Create a shadow root
const shadow = this.attachShadow({mode: 'open'});
// Create text node and add word count to it
const text = document.createElement('span');
text.textContent = count;
// Append it to the shadow root
shadow.appendChild(text);
// Update count when element content changes
setInterval(function() {
const count = `Words: ${countWords(wcParent)}`;
text.textContent = count;
}, 200);
}
}
// Define the new element
customElements.define('word-count', WordCount, { extends: 'p' });
전통 적인 마크업 구조에서는 스타일과 기능을 재사용 하기 쉽지 않은 구조를 가지고 있다.
이를 해결 하기 위해 웹 컴포넌트는 아래 세 가지 주요 기술을 이용해 커스텀 엘리먼스를 생성 할 수 있게 한다.
설명만 보면 우리가 흔히 사용하는 React, vue등과 비슷한 역할을 하는 것 같아 보인다. Web Components는 이런 UI Framework or Library를 사용할 수 없는 경우에 유용하게 쓸 수 있을 것 같다.
예를 들어 본인의 경우 이미지를 업로드전에 간단하게 편집 가능한 에디터를 구현하는데 구현 목표 중 하나가 UI framework 혹은 library에 종속 되지 않도록 하려고 한다.
이런 경우 HTML5 스팩을 이용한 Web Components로 개발 한다면 의존성 없이 동작 하는 라이브러리로 구현 가능 할 것이다.