본문은 위시켓과 번역가 윌리(Willy)가 함께 만든 해외 콘텐츠 기반 번역문입니다. 자바스크립트 및 웹 개발 콘텐츠를 제공하는 in Plain English 블로그의 ‘Will Web Components Replace Frontend Frameworks?’ 글을 번역했습니다. 필자인 Marius Bongarts는 소프트웨어 엔지니어링 분석가로 개발 언어에 대한 분석 글을 작성하고 있습니다. 본문은 웹 컴포넌트와 프론트엔드 프레임워크가 어떻게 쓰이고 둘은 어떤 시너지를 낼 수 있는지 설명합니다.
본문은 위시켓과 번역가 윌리(Willy)가 함께 만든 해외 콘텐츠 기반 번역문입니다. 자바스크립트 및 웹 개발 콘텐츠를 제공하는 in Plain English 블로그의 ‘Will Web Components Replace Frontend Frameworks?’ 글을 번역했습니다. 필자인 Marius Bongarts는 소프트웨어 엔지니어링 분석가로 개발 언어에 대한 분석 글을 작성하고 있습니다. 본문은 웹 컴포넌트와 프론트엔드 프레임워크가 어떻게 쓰이고 둘은 어떤 시너지를 낼 수 있는지 설명합니다.
글 제목에 물음표가 들어가 있으면 그 답은 "아니오"일 가능성이 크다. - Ian Betteridge
Betteridge의 법칙은 본 글에서 다룰 주제에 대한 우리 모두의 생각을 잘 대변하고 있습니다. 저는 웹 컴포넌트와 앵귤러(Angular)[1], 리액트(React)[2], 뷰(Vue.js)[3] 등과 같은 자바스크립트 프레임워크 사이에서 벌어지는 전쟁을 이해할 수 없습니다. 오히려 이 둘을 결합하면 훨씬 쉽고 효율적인 프론트엔드[4] 개발이 가능합니다.
시작하기 앞서, 리액트는 프레임워크가 아닌 라이브러리이지만 이 글의 목적을 위해 편의상 프레임워크라고 부르겠습니다.
리액트를 사용하여 매우 복잡한 웹 애플리케이션을 개발한 회사가 있다고 가정해 보겠습니다. 수백 명의 정규직 개발자가 여기에 매달리고 있습니다. 그들은 리액트 컴포넌트 라이브러리를 자체 개발하여 지금까지 사용하던 UI 컴포넌트(버튼, 입력 폼, 대화 상자 등)를 언제든지 재사용할 수 있도록 개선했습니다. 이는 시스템 내에서 코드 중복을 최소화하는 데 도움이 되겠죠. 아주 훌륭합니다!
하지만 소프트웨어 산업은 하루가 다르게 발전하고 변하는 산업 중 하나입니다. 이는 소프트웨어 엔지니어링의 많은 변화와 혁신으로 이어집니다. 내년에 갑자기 기존의 모든 프레임워크를 압도할 궁극적인 프론트엔드 프레임워크가 출시된다고 가정해 보겠습니다.
점점 더 많은 개발자들이 이 새로운 프레임워크 사용하겠죠. 앞서 설명한 회사는 일부 프로젝트에 새 프레임워크를 적용하고, 다시 몇 년에 걸쳐 기존 컴포넌트를 마이그레이션할 것입니다. 리액트는 더 이상 최선의 선택이 아니며, 좋은 리액트 개발자를 찾는 것은 점점 더 힘들어지고 큰 비용이 들 것입니다.
벤더 락인(Vendor lock-in)은 새로운 솔루션으로 전환하는 비용이 너무 많이 들어서 기존 업체나 솔루션을 어쩔 수 없이 계속 사용하게 되는 상황을 의미합니다.
이 회사는 이제 새로운 프레임워크에 뒤처지는 프론트엔드 라이브러리인 리액트에 락인(Lock-in) 되고 말았습니다. 새 프레임워크로 전환하려면 큰 비용이 들어가고 운영 중인 비즈니스에 영향을 줄 수 있습니다. 회사의 애플리케이션이 사용하는 모든 프론트엔드 컴포넌트를 새 프레임워크로 마이그레이션 해야 합니다.
"벤더 락인은 그 품질과는 별개로 누군가가 특정 제품이나 서비스를 계속 사용하도록 강요받는 것입니다." - cloudflare.com
이 회사는 벤더 락인으로 인한 손해를 줄이기 위해 무엇을 할 수 있었을까요?
표준 기술을 사용하면 변화에 좀 더 유연하게 대처할 수 있습니다. 예시에 등장한 회사는 기존 UI 컴포넌트를 웹 컴포넌트로 바꿀 수도 있었습니다. 심지어 리액트 공식 문서도 웹 컴포넌트를 사용할 것을 제안하고 있습니다.
리액트를 사용하는 대부분의 사람들은 웹 컴포넌트를 사용하고 있지 않지만 웹 컴포넌트로 만든 써드파티 UI 컴포넌트라면 충분히 고려해 볼 것입니다. - https://reactjs.org
웹 컴포넌트는 여러 프로젝트에서 공유할 수 있는 재사용 가능한 요소에 대해 강력한 캡슐화를 제공하지만, 리액트는 DOM과 데이터의 동기화를 유지하기 위해 선언적 라이브러리(declarative library)를 제공합니다. 사실 이 두 가지는 상호 보완적인 관계입니다.
"개발자는 리액트를 웹 컴포넌트에 사용하거나 웹 컴포넌트를 리액트에 사용할 수 있으며, 이 두 가지 방식을 동시에 사용할 수도 있습니다." -reactjs.org
재사용 가능한 버튼을 만드는 데 꼭 리액트를 사용할 이유는 없습니다. 즉, 컴포넌트를 공유해야 하는 서로 다른 기술 스택의 여러 프로젝트를 진행하려면 웹 컴포넌트가 적합합니다.
웹 컴포넌트를 배워야 하는 이유
웹 컴포넌트를 사용하면 벤더 락인에서 벗어날 수 있으며, 다음과 같은 많은 장점을 누릴 수 있습니다.
웹 컴포넌트는 널리 되고 있습니다.
아래 차트는 크롬에서 customElements.define을 한 번 이상 호출하는 페이지의 비율을 보여줍니다.
크롬 브라우저에서 동작한 모든 웹사이트의 15% 이상이 커스텀 엘리먼트(Custom Element)[6]를 하나 이상 등록한 것으로 나타났습니다. 반면, w3techs.com에 따르면 전체 웹사이트의 2.3%만이 리액트를 사용하고 있습니다.
프론트엔드 프레임워크는 웹 컴포넌트를 지원합니다.
리액트가 캡슐화되고 재사용 가능한 웹 컴포넌트의 생성을 지원한다는 사실을 앞에서 언급한 바 있습니다. 사실 리액트뿐만 아니라 앵귤러와 Vue.js도 이를 지원하고 있습니다.
앵귤러를 먼저 살펴보겠습니다. 앵귤러는 개발자가 컴포넌트를 웹 컴포넌트로 빠르게 변환할 수 있도록 @angular/elements 패키지를 제공합니다.
"앵귤러 엘리먼트는 커스텀 엘리먼트로 패키지 한 앵귤러 컴포넌트이다." - angular.io
또한, Vue.js는 defineCustomElement 메소드를 통해 웹 컴포넌트를 지원하고 있습니다.
"Vue는 완전히 동일한 Vue 컴포넌트 API를 사용하여 커스텀 엘리먼트 생성을 지원합니다." - vuejs.org
여러분에게 이미 친숙한 문법을 구사합니다.
우리가 이미 알고 있듯이 많은 최신 프론트엔드 프레임워크는 웹 컴포넌트를 지원합니다. 그중 일부, 특히 Vue.js는 웹 표준을 기반으로 만들어졌습니다.
웹 컴포넌트의 세 가지 주요 기술인 커스텀 엘리먼트, 쉐도우 돔(Shadow DOM)[7], HTML 템플릿을 알고 있다면 자바스크립트 프레임워크가 어떻게 이를 지원하는지 쉽게 이해할 수 있습니다.
Vue.js 개발 경험이 있다면 scoped 속성을 사용하여 스타일이 적용되는 범위를 지정하는 것에 익숙할 것입니다.
<style scoped>/* local styles */</style>
scoped 속성은 Vue.js 컴포넌트 지정한 컴포넌트 요소에만 스타일이 적용되도록 제한합니다. 웹 컴포넌트의 세 가지 주요 기술에 익숙하다면 Vue.js가 쉐도우 돔을 사용하고 있다는 사실을 이미 알고 계실 것입니다.
"이것은 쉐도우 돔에서 사용하는 스타일 캡슐화(style encapsulation)과 유사합니다." - vuejs.org
쉐도우 트리(Shadow Tree)를 사용하면 컴포넌트의 마크업과 스타일을 페이지의 다른 코드와 분리할 수 있습니다. 이를 통해 웹사이트를 구성하는 서로 다른 영역의 스타일을 섞이는 것을 방지할 수 있습니다. 쉐도우 돔에 대해 자세히 알아보려면 다음 글을 확인해보세요. (완벽한 웹 컴포넌트 가이드: 쉐도우 돔(Shadow DOM))
새로운 프론트엔드 프레임워크를 쉽게 배울 수 있습니다.
흔히 하나의 프로그래밍 언어를 마스터하면 다른 언어를 배우기 쉽다고 말합니다. 이는 프론트엔드 프레임워크에서도 마찬가지입니다.
저는 운 좋게도 대학에서 웹 컴포넌트에 대한 기초를 배울 수 있었습니다. 그전까지는 앵귤러를 사용했습니다. 그리고 지금까지 리액트, Vue.js, 앵귤러 이 세 가지 프레임워크를 모두 사용해봤습니다.
가장 마지막으로 배운 것은 리액트였습니다. 이미 웹 컴포넌트와 다른 두 프레임워크를 상용한 경험이 있었기 때문에 리액트를 배우는 것은 어렵지 않았습니다. 문법은 조금씩 달라도 컴포넌트를 생성한다는 공통점이 있습니다. DOM 트리 위나 아래로 데이터를 전달하고 데이터를 렌더링해 보여주는 것이죠.
네트워크 효과
웹 개발자라면 한 번쯤 머티리얼 디자인(Material Design) 프레임워크를 사용해 봤을 것입니다. 앵귤러용 Angular Material, Vue.js용 Vuetify, 리액트용 Material UI를 포함하여 무수히 많은 프레임워크가 있습니다. 이 중 어떤 것을 훌륭하고 어떤 것은 별 볼일 없겠지만 결국 모든 프레임워크는 버튼, 입력 폼, 대화 상자 등과 같이 비슷하며 재사용 가능한 UI 컴포넌트를 제공하고 있습니다. 그런데도 이를 각 프레임워크마다 따로 구현하고 있습니다.
만약 하나로 통합된 웹이 존재해서 모두가 웹 컴포넌트를 공유할 수 있다면 멋지지 않을까요? 그렇다면 프레임워크에 신경 쓰지 않아도 최고의 UI 컴포넌트를 선택할 수 있습니다. 또한, 자바스크립트 프레임워크에 대한 종속성에서 해방될 수 있겠죠. 웹 컴포넌트를 사용하면 프레임워크를 변경할 때 발생하는 비용을 크게 줄일 수 있습니다.
만약 Lit 또는 Stencil과 같은 라이브러리를 사용하고 있다면 최신 자바스크립트 라이브러리를 사용하는 것보다 쉬울뿐더러 개발 방식도 크게 다르지 않습니다. 웹 컴포넌트를 사용하여 자신의 블로그 포트폴리오를 만들려면 다음 글을 참고해 보세요. (웹 컴포넌트로 나만의 블로그 포트폴리오 만들기: 기본편)
가장 기본적인 HTML, CSS, JavaScript로 시작해Lit 라이브러리를 사용하는 쉬운 개발 방식을 익힐 수 있습니다.
정리하며
웹 컴포넌트가 가까운 미래에 프론트엔드 프레임워크를 대신할 일은 없습니다. 대신 컴포넌트 계층을 하나로 통일된 네이티브 솔루션으로 교체함으로써 기존 프레임워크를 더욱 발전시킬 수 있습니다.
[1] 구글이 2010년 출시한 타입스크립트 기반 자바스크립트 프레임워크.
[2] 사용자 인터페이스 개발을 위해 페이스북에서 만들고 공개한 오픈소스 자바스크립트 라이브러리.
[3] 웹 애플리케이션의 사용자 인터페이스를 만들기 위해 사용하는 오픈소스 프로그레시브 자바스크립트 프레임워크.
[4] 웹에서 동작하는 UI(User Interface) 부분을 말하며, 사용자가 눈으로 보고 인식할 수 있는 영역.
[5] 관련이 있는 변수와 함수를 하나로 묶어 외부에서 쉽게 접근하지 못하도록 은닉하는 것.
[6] 사용자가 정의한 HTML태그를 자동으로 HTML element(즉, DOM object)로 연관시켜주는 브라우저 기능.
[7] 구조 자체는 일반 DOM과 같지만, 외부에 노출되지 않고 외부 스타일에 영향을 받지 않는 DOM을 지칭함.