안녕하세요. 꼬동입니다.
최근 웹 프론트엔드 프레임워크를 공부하다가, 의문이 생긴 것들이 있습니다.
바로 "컴포넌트 기반 개발 프레임워크"라는 말입니다.
아래 글에서도 이를 기반으로 글을 작성했더군요.
www.samsungsds.com/kr/insights/frameworks.html
"~ 기반 개발 프레임워크"는 뭐 그렇다고 친다만, "컴포넌트" 얘는 뭘까요?
뭐.. 독립된 하나의 부품?? 으로 이해할 수 있겠다만, 좀 더 자세히 알아야하지 않을까 싶어서, 찾아보다가 W3C에서 웹 컴포넌트를 정의한 글이 있더군요.
W3C는 월드 와이드 웹을 위한 표준을 개발하고 장려하는 조직입니다.
그리고 보통 컴포넌트를 독립적인 뷰를 생성하기 위해서 HTML CSS JS를 한 곳에 묶어놓은 것이라고 알고 있으면 되겠습니다.
아 물론 영어입니다.
www.webcomponents.org/introduction
허나 친절한 꼬동, 이를 번역해서 여러분들이 "웹 컴포넌트"에 대한 이해를 할 수 있도록 노력해보겠습니다.
웹 컴포넌트란?
웹 컴포넌트는 웹 페이지 혹은 웹 앱에서 커스텀화 / 재사용화 / 캡슐화된 HTML 태그를 만들 수 있는 웹 플랫폼 APIs의 집합입니다.
웹 컴포넌트 기반을 둔 커스텀 컴포넌트와 위젯은 최신 브라우저에서 작동되며, 자바스크립트 라이브러리와 프레임워크 역시 HTML과 함께 사용할 수 있습니다.
웹 컴포넌트는 웹 표준을 기반으로 합니다. 웹 컴포넌트를 지원하는 기능은 HTML과 DOM 스펙에 추가되고 있으며, 웹 개발자들은 쉽게 캡슐화된 스타일링과 커스텀 동작들이 탑재된 엘리멘트를 이용해서 HTML를 확장할 수 있습니다.
특징
웹 컴포넌트는 총 4가지의 주 특징이 있습니다.
- 커스텀 엘리먼트 => 커스텀 엘리먼트는 DOM 엘리먼트의 새로운 타입을 디자인하고 사용하기 위해 기반을 제공합니다.
- Shadow DOM => Shadow DOM은 웹 컴포넌트 안에 있는 마크업과 캡슐화된 스타일을 어떻게 사용하는지를 정의합니다.
- ES Modules => ES Modules은 JS 문서의 재사용성을 제공합니다.
- HTML 템플릿 => 페이지 로드에서는 사용되지 않지만, 런타임에서 인스턴스화를 할 수 있는 마크업을 제공합니다.
번역하면서도 좀 긴가민가 했는데, 아래와 같습니다.
1. 커스텀 엘리먼트 => 컴포넌트를 새로운 명칭으로 만들어 이를 HTML 요소와 함께 사용한다.
2. Shadow DOM => 컴포넌트끼리는 스코프를 분리하여 DOM을 캡슐화한다.
3. ES Modlues => 컴포넌트끼리 호출할 수 있다. (import, <script type="module"></script>)
4. HTML 템플릿 => 컴포넌트의 뷰를 생성한다.
위의 조건 4가지가 웹 컴포넌트의 특징이라고 생각하시면 됩니다.
웹 컴포넌트 사용 방법
커스텀 엘리먼트를 사용하는 것은 간단합니다. import 하고 HTML 문서에 새로운 태그를 사용하면 됩니다.
<script type="module" src="node_modules/@polymer/paper-button/paper-button.js"></script>
...
<paper-button raised class="indigo">raised</paper-button>
커스텀 엘리먼트를 설치하는 방법은 많습니다.
만약 사용하고 싶은 엘리먼트를 찾았다면, README를 찾아서 설치하기 위한 커맨드를 찾으면 됩니다.
요즘 날의 대부분의 엘리먼트들은 NPM을 이용하여 설치가 됩니다.
이렇게 할 수 있겠네요.
mkdir my-new-app && cd my-new-app
npm install --save @polymer/paper-button
어떻게 새로운 HTML 엘리먼트를 정의할 수 있을까요?
새로운 HTML 엘리먼트를 정의하고 싶으시면, JS를 쓰면 됩니다.
customElements.define() API를 이용하면 새로운 태그 이름을 만들 수 있습니다.
class AppDrawer extends HTMLElement {...}
window.customElements.define('app-drawer', AppDrawer);
그리고 사용하면 됩니다.
<app-drawer></app-drawer>
커스텀 엘리먼트를 사용하는 것은 <div> 태그를 사용하는 것과 다르지 않습니다.
또한, 동적으로 만들 수 있으며, 이벤트 리스너 역시 붙일 수 있죠.
<script>
var newDrawer = document.createElement('app-drawer');
document.body.appendChild(newDrawer);
document.querySelector('app-drawer').addEventListener('open', function() {...});
</script>
Shadow root를 만들고 사용하기
이번 섹션에서는 shadow DOM을 만들고 사용하는 방법을 얘기해봅시다.
Shadow DOM은 컴포넌트를 빌드시켜주는 새로운 DOM 기능 입니다. 이를 엘리먼트안에 있는 서브트리라고 생각하시면 되겠네요.
Shadow root는 element.attachShadow()로 만들 수 있습니다.
const header = document.createElement('header');
const shadowRoot = header.attachShow({mode: 'open'});
shadowRoot.innerHTML = '<h1>Hello Shadow DOM</ha>';
Shadow DOM
사실 이 부분은 제가 앞서 올린 글에 포함되지 않는 부분입니다.
근데 Shadow DOM이 유독 이해하기가 힘들어서 더 찾아봤습니다.
해당 글에서 그나마 더 자세히 알려주더라고요.
그래서 위 글에서의 Shadow DOM 부분만 번역해서 얘기를 나눠봅시다. (다른 애들은 위 내용과 비슷비슷 합니다)
앞서 Shadow DOM을 스코프를 분리하여, DOM을 캡슐화 시킨다라고 말씀드렸습니다.
그 예를 들 수 있는 코드를 봅시다.
<style>
body { color: white; }
.test { background-color: red; }
</style>
<styled-element>
#shadow-root
<style>
div { background-color: blue; }
</style>
<div class="test">Test</div>
</styled-element>
아래 코드는 스타일 안에 Shadow tree로 스코프가 감싸져있으며, Shadow tree 밖의 영역엔 영향을 주지 않습니다.
마찬가지로 밖의 style은 shadow tree에 영향을 주지 않습니다. 그런데, 상속가능한 color와 같은 style 프로퍼티들은 shadow tree로 상속이 됩니다.
위의 코드에서 <div>는 파란색 배경이 있습니다. .test selector가 red라고 선언이 됐음에도요.
그 이유가 <div>는 shadow DOM에 있기 때문입니다.
반면 white text color의 경우엔 상속이 돼서 shadow DOM 내이지만, white 색이 띄워집니다.
이러한 특성은 Angular에서도 적용됩니다.
해당 heros에 작성된 컴포넌트 스타일은 해당 컴포넌트를 위한 것입니다. 어떻게 이렇게 될 수 있을까요?
이와 같은 특성은 웹 컴포넌트의 Shadow DOM을 구현한 것으로 컴포넌트의 DOM을 캡슐화하여 외부로부터의 간섭을 제어합니다.
변수 스코프와 유사하죠.
번역에 미흡한 부분도 많고, 컴포넌트에 대한 이해가 부족한 상황에서 글을 쓰다 보니 부족한 부분이 많습니다.
이상 웹 컴포넌트란? 였습니다. ^_^
'Web + APP' 카테고리의 다른 글
iOS App with Watch App과 Watch App 차이 (0) | 2021.11.20 |
---|---|
브라우저는 어떻게 동작하는가. (간단 요약) (0) | 2021.03.14 |