IT개발

웹 컴포넌트(Web Components) 실전 활용법

우리모두 개발자되기 2025. 4. 24. 08:40

 

웹 컴포넌트(Web Components) 실전 활용법: 프레임워크에 구애받지 않는 UI의 미래

최근 몇 년간 웹 개발에서 ‘재사용성’, ‘모듈화’, ‘호환성’은 매우 중요한 키워드가 되었습니다. React, Vue, Angular 등 프레임워크마다 컴포넌트 기반 설계를 도입했지만, 이들은 각자 고유한 생태계 안에서 동작합니다.

 

이런 상황에서 등장한 것이 바로 **웹 컴포넌트(Web Components)**입니다. 웹 컴포넌트는 브라우저가 표준으로 지원하는 컴포넌트 시스템으로, 프레임워크에 종속되지 않고 어디서나 사용할 수 있다는 점에서 많은 주목을 받고 있습니다.

이번 글에서는 웹 컴포넌트의 기본 개념부터 실전 사용법, 그리고 실무 적용 시 고려할 점까지 자세히 설명드리겠습니다.


1. 웹 컴포넌트란?

웹 컴포넌트는 다음 4가지 기술을 조합해 구현합니다.

  1. Custom Elements: 사용자 정의 태그를 만들 수 있도록 하는 API
  2. Shadow DOM: 컴포넌트 내부 DOM을 외부와 분리된 범위로 캡슐화
  3. HTML Templates: HTML 마크업을 사전 정의하고 재사용
  4. ES 모듈: 모듈화된 자바스크립트로 컴포넌트 구조화

즉, <my-button> 같은 사용자 정의 태그를 만들고, 그 내부는 다른 CSS나 DOM과 충돌하지 않도록 격리할 수 있습니다.


2. 웹 컴포넌트 기본 구조

아래는 웹 컴포넌트의 대표적인 구조입니다:

<my-greeting></my-greeting>

<script>
  class MyGreeting extends HTMLElement {
    constructor() {
      super();
      const shadow = this.attachShadow({ mode: 'open' });
      shadow.innerHTML = `<p>Hello, Web Component!</p>`;
    }
  }

  customElements.define('my-greeting', MyGreeting);
</script>

설명:

  • MyGreeting 클래스는 HTML 요소를 상속받아 정의됩니다.
  • attachShadow() 메서드를 통해 Shadow DOM을 생성합니다.
  • customElements.define()으로 사용자 정의 태그를 등록합니다.

이제 HTML 어디에서든 <my-greeting></my-greeting>을 사용할 수 있습니다.


3. Shadow DOM의 역할

Shadow DOM은 웹 컴포넌트의 가장 핵심적인 기능입니다.
CSS와 DOM을 컴포넌트 단위로 완벽히 격리시켜줍니다.

const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
  <style>
    p { color: red; }
  </style>
  <p>This text is red, but only inside the component</p>
`;

이렇게 하면 외부 페이지의 CSS는 컴포넌트 내부에 영향을 주지 않으며, 반대로 컴포넌트의 스타일이 외부에 영향을 주지도 않습니다.


4. HTML 템플릿 사용

웹 컴포넌트는 템플릿을 활용해 효율적인 컴포넌트 렌더링을 할 수 있습니다.

<template id="card-template">
  <style>
    .card { border: 1px solid #ccc; padding: 10px; }
  </style>
  <div class="card">
    <slot></slot>
  </div>
</template>

<script>
  class MyCard extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById('card-template').content;
      const shadow = this.attachShadow({ mode: 'open' });
      shadow.appendChild(template.cloneNode(true));
    }
  }

  customElements.define('my-card', MyCard);
</script>

<my-card>여기에 들어갈 콘텐츠</my-card>

<slot> 태그는 부모 요소에서 전달한 콘텐츠를 표시해주는 역할을 합니다. React의 children과 비슷합니다.


5. 실전 활용: 상태 기반 인터랙션

class ToggleButton extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });

    let toggled = false;

    const button = document.createElement('button');
    button.textContent = 'OFF';
    button.addEventListener('click', () => {
      toggled = !toggled;
      button.textContent = toggled ? 'ON' : 'OFF';
    });

    shadow.appendChild(button);
  }
}

customElements.define('toggle-button', ToggleButton);

이렇게 간단한 상태 관리를 통해 버튼의 텍스트를 토글하는 UI도 만들 수 있습니다. 외부 프레임워크 없이도 DOM과 상태를 연결할 수 있다는 것이 장점입니다.


6. 웹 컴포넌트 vs 프레임워크 컴포넌트

항목 웹 컴포넌트 React/Vue 등 프레임워크

브라우저 지원 대부분 최신 브라우저 지원 브라우저에 직접 종속 X
런타임 필요 없음 있음 (가상 DOM 등)
퍼포먼스 빠름 (직접 DOM 조작) 가상 DOM 기반으로 효율적
학습 난이도 비교적 쉬움 라이프사이클 등 복잡도 있음
프레임워크 독립성 완전 독립적 해당 프레임워크에 종속
복잡한 상태 관리, 라우팅 직접 구현 필요 라이브러리 생태계 풍부

7. 실무에서 어떻게 활용할까?

a. 디자인 시스템 구축

기업에서 웹 컴포넌트를 가장 많이 사용하는 분야 중 하나가 디자인 시스템 구축입니다.
버튼, 카드, 입력창 등 UI 요소들을 프레임워크와 무관하게 사용할 수 있어 React, Vue, Angular 어디서나 재사용 가능합니다.

b. 마이크로 프론트엔드(Micro Frontend)

여러 팀이 서로 다른 프레임워크로 애플리케이션을 개발해야 할 경우, 공통 컴포넌트를 웹 컴포넌트로 제공하면 기술 독립성과 일관성을 동시에 확보할 수 있습니다.

c. CMS나 기존 시스템 연동

WordPress, Drupal 등 기존 시스템에서도 쉽게 포함시킬 수 있는 점이 큰 장점입니다.


8. 웹 컴포넌트의 한계

  • IE 지원 없음
  • 상태 관리가 제한적 (Redux, Vuex 등 없음)
  • SSR (서버 사이드 렌더링) 기능 부족
  • 규모가 커질수록 코드 유지보수 난이도 증가

→ 해결 방법:
Lit, Stencil, Haunted 등 웹 컴포넌트 기반 라이브러리를 활용하면 이런 문제를 어느 정도 해결할 수 있습니다.


9. 결론

웹 컴포넌트는 이제 단순한 기술 트렌드를 넘어, 다양한 프레임워크를 넘나드는 진정한 재사용 가능한 UI 구성 요소로 자리 잡고 있습니다.

특히 웹 표준 기술 기반이라는 점에서 장기적으로 유지보수 가능한 UI를 만들고자 할 때 매우 강력한 도구가 됩니다. 초기 진입 장벽은 낮지만, 제대로 활용하려면 Shadow DOM, Slot, 이벤트 처리 등 다양한 브라우저 API에 익숙해져야 합니다.

단순한 프로젝트부터 시작해 점차 범위를 넓혀 나가면, 프레임워크에 종속되지 않는 유연한 개발 역량을 확보할 수 있을 것입니다.