티스토리 뷰

다음 글의 번역입니다. [The state of Web Components - Wilson Page]

If writer does not want this article, please contact me.(han41858@gmail.com)


내용이 길어서 나눠서 글 작성합니다. Web Components의 현 주소(1) 에서 이어집니다.


 Shadow piercing combinators

 'piercing combinator' 는 CSS 선택자의 특별한 경우이며 shadow root 안쪽의 엘리먼트를 밖에서도 지정할 수 있다. 원래 이름은 /deep/ 이었지만 나중에 >>> 로 변경되었다.

.foo >>> div { color: red }

 웹 컴포넌트가 처음 구체화 되었을 때, 이런 사항이 필요할 것으로 생각되었지만 어떻게 사용해야 할지 논의가 되다 보니, 오히려 영역의 스타일을 파괴하는 문제만을 야기했다.


성능

 Shadow DOM 내부에서는 엔진이 외부 선택자나 상태를 고려하지 않기 때문에 스타일 연산이 매우 빠르다. 이런 점은 piercing combinator 를 사용하는 아주 중요한 이유다.


대안

 shadow piercing combinators를 빼게 되면 사용자는 컴포넌트 밖에서는 절대로 모양을 바꿀 수 없기 때문에 다른 방법이 논의되기도 했다.


CSS 커스텀 속성 (변수 사용)

 Firefox OS에서는 CSS 커스텀 속성을 사용하여 Shadow DOM외부에서도 스타일을 지정하고 있다.

 외부에서는 이렇게 쓴다.

x-foo { --x-foo-border-radius: 10px; }

내부에서는 이렇게.

.internal-part { border-radius: var(--x-foo-border-radius, 0); }


커스텀 유사(pseudo) 엘리먼트

 벤더들이 내부 조각에 스타일을 입히기 위해 유사 엘리먼트를 정의하는 몇가지 유사 선택자 패턴을 살펴봤다.

x-foo::my-internal-part { ... }

 위에 있는 코드는 Shadow DOM V2 표준안으로 거론되고 있는 형식이다.


@extend를 활용

 SASS의 @extend를 가져와서 제안된 방식도 있다. 이 방식은 컴포넌트 제작자에게는 외부의 속성을 내부로 전달할 수 있다는 점에서 유용하다.


외부에서(사용자) :

.x-foo-part {
  background-color: red;
  border-radius: 4px;
}


내부에서(컴포넌트 작성자) :

.internal-part {
  @extend .x-foo-part;
}



다중 shadow root

 하나의 엘리먼트에 왜 여러개의 shadow root가 필요할까? 그 이유는 상속 때문이다.

 <x-dialog> 라는 컴포넌트를 만들었다고 하자. 이 컴포넌트에서는 대화상자를 열고 닫는 동작과 마크업, 스타일을 모두 작성해두었다.


  

My title

Some details

 shadow root는 div.inner 안에 있는 <content> 진입점을 바탕으로 내용물을 구성한다.

 이제 <x-dialog> 와 비슷한 동작을 하는 <x-dialog-alert> 컴포넌트를 만들려고 하지만, 좀 더 제한적인 API를 이용하여 바꿔보려고 한다.

foo

var proto = Object.create(XDialog.prototype);

proto.createdCallback = function() {
  XDialog.prototype.createdCallback.call(this);
  this.createShadowRoot();
  this.shadowRoot.innerHTML = templateString;
};

document.registerElement('x-dialog-alert', { prototype: proto });

 새로 만든 컴포넌트는 자체적인 shadow root를 가지지만, 부모 클래스의 shadow root를 위해 작성된 것을 가져온 것이다. 아래에서 <shadow> 는 '이전의' shadow root 를 가리키며 원래 넣으려고 하던 내용을 이 안으로 가져온다.


  

Alert

 다중 shadow root를 한 번 접하게 되면, 이 컨셉이 강력한 것임을 알게 될 것이다. 아래에서 좀 더 복잡한 내용으로 실제 활용도를 살펴보자.


다중 shadow 를 이용한 상속

 다중 shadow root 없이도 상속은 가능하지만, 부모 클래스의 shadow root를 수동으로 조작해야 한다.

var proto = Object.create(XDialog.prototype);

proto.createdCallback = function() {
  XDialog.prototype.createdCallback.call(this);
  var inner = this.shadowRoot.querySelector('.inner');

  var h1 = document.createElement('h1');
  h1.textContent = 'Alert';
  inner.insertBefore(h1, inner.children[0]);

  var button = document.createElement('button');
  button.textContent = 'OK';
  inner.appendChild(button);

  ...
};

document.registerElement('x-dialog-alert', { prototype: proto });


단점 :

  1. 방식이 우아하지 않다.
  2. 자식 컴포넌트는 부모 컴포넌트의 구현 방식을 따라가게 된다.
  3. 부모 컴포넌트의 shadow root가 '닫힌' 상태이면 this.shadowRoot가 undefined가 될것이므로 이런 경우에는 불가능하다.



HTML Imports

 HTML Import를 사용하면 하나의 .html 문서 안에 있는 모든 항목을 다른 영역으로 가져올 수 있다.


 이전에 작성한 글처럼 Mozilla는 HTML Import 도입을 고려하고 있지 않다. 외부의 컴포넌트를 불러오는 다른 방법이 마련되기 이전에 ES6의 모듈이 어떻게 발전할지를 주목하고 있기 때문이다.

 우리는 Firefox OS로 Web Components를 1년 이상 작업해왔지만 지금 나와 있는 모듈 문법(AMD나 CommonJS)으로 트리를 구성하거나 엘리먼트를 등록하고 기본적인 <script> 태그를 이용하는 것도 문제가 없었다.

 HTML Import는 이런 동작들은 좀 더 간단하고 명확하게 만들어줄것이며, 이전의 <element>Polymer의 현재 문법보다 더 좋아질 것이다.

 이런 간단함에도 불구하고 커뮤니티에서는 Import가 의존성 관리의 해결책으로서 제대로 된 기능을 제공하지 못한다는 우려가 있기도 하다.

 몇 달 전 결론이 나기 전까지(역주 : 원문의 작성 시점은 2015년 6월입니다.), Mozilla는 HTML Import의 구현을 위해 힘썼지만 불완전한 표준안에서는 어려운 일이었다.


그리고 어떤 일이 있었나?

 Apple이 독립된 커스텀 엘리먼트에 대한 제안을 낸 이후, HTML Import 스타일은 커스텀 엘리먼트를 자체 스코프를 가진 컴포넌트를 만드는 방향으로 변화했다. 아마도 나중에 완성이 되겠지만.

 Mozilla에서는 ES6 모듈 API와 커스텀 엘리먼트 정의를 어떻게 함께 다루어야 할 것인지에 집중하고 있다. 개발자들이 이런 것들에 대한 필요가 느껴질 때를 위해 우리는 미리 준비를 해두려고 한다.



결론

 Web Component는 대단위 기능 요구사항이 브라우저에 자리잡기까지 얼마나 어려운지 보여주는 하나의 예다. 모든 API가 개별적으로 만들어졌고 어떤 어려움을 넘어야 하는 지도 각각 다르다.

 실타래가 얽혀 있는 큰 뭉치와 비슷할 수 있는데, 무언가를 좀 더하고 어떤 부분을 해결하는 것의 반복이다. 우리 플랫폼(역주 : Mozilla Firefox OS)은 점점 커지고 복잡해지고 있다.

 Web Component는 3년 이상 계획을 갖고 진행되었고 그 끝이 가까워졌다고 생각한다. 모든 주류 브라우저 벤더들이 그 내용을 준비하고 있고, 열정과 시간이 좀 더 투입된다면 남은 문제들도 시결할 수 있을 것이다.


 컴포넌트와 함께하는 웹으로 갈 준비가 되었는가!

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함