Web Components e a minha opinião sobre o futuro das libs front-end
Published: 2024-04-04 12:50:36

Eu tô ficando velho. E como todo velho, eu ganho licença poética pra prever eventos futuros baseados em eventos passados. Tem dia que eu sei que vai chover, tem dia que eu sei que vai ser bom, e tem dia que eu consigo escrever.

Eu tenho trabalhado bastante com web components nos últimos anos, e tô realmente impressionado com o quanto eu consegui escalar o desenvolvimento das minhas libs depois que eu passei a utilizá-los, então esse post é pra compartilhar minha experiência e explicar por que eu acredito que o futuro das libs é por esse caminho.

## Tá, mas o que são web components?

Eu copiei essa definição do [site da Mozilla](https://developer.mozilla.org/pt-BR/docs/Web/API/Web_components) (MDN): Web Components é uma suíte de diferentes tecnologias que permite a criação de elementos customizados reutilizáveis — com a funcionalidade separada do resto do seu código — e que podem ser utilizados em suas aplicações web.

E a minha explicação de dev simplão é: Web Components são componentes similares aos do react, angular, etc, mas que rodam em qualquer lugar e são nativos do browser. Você cria um componente `<ric-header></ric-reader>` e pode usar em qualquer lugar que vai funcionar, assim como o nosso bom e velho javascript.

## Em qualquer lugar?

Sim. Na ~~p$#%@~~ coisa toda. Você pode usar o mesmo componente em um site wordpress, em um site HTML igual aos que eu fazia em 2010, ou em uma SPA react/angular/seuframeworkaqui.

Os Web Components são nativos do browser, e por isso você não precisa de nenhuma mágica para renderizar. Desde que um browser moderno seja utilizado, você realmente pode utilizar o web component em uma página HTML básica ou integrar ao seu site em React.

E sobre browsers modernos, [aqui está a especificação do caniuse](https://caniuse.com/custom-elementsv1). Todos os browsers atuais são compatíveis, com exceção do nosso já conhecido Opera Mini e [desse "bug"](https://bugs.webkit.org/show_bug.cgi?id=182671) no Safari.

![Tabela de suporte dos navegadores aos web components: all green](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vatsu0r9a76qct8hjnzu.png)


### Bug no Safari?

Na verdade é a falta de suporte ao atributo `is=""`, e que está categorizada como WONTFIX no bugzilla. Nessa especificação, nós poderíamos customizar as tags nativas do HTML com esse atributo. Porém, não vai impactar em muita coisa porque podemos alcançar o mesmo resultado de outra forma.

Em resumo, você poderia registrar usar um componente de parágrafo customizado assim:

```js
customElements.define("word-count", WordCount, { extends: "p" });
```

E utilizar o componente com esse código:

```html
<p is="word-count"></p>
```

Porém, o mesmo comportamento pode ser alcançado registrando um novo componente assim:

```js
customElements.define("word-count", WordCount);
```

E usando o componente:
```html
<word-count></word-count>
```

Eu sei que a gente perde um pouco da flexibilidade por precisar de uma tag nova, mas não tem muito o que fazer a não ser reclamar na issue pra ver se a galera do safari implementa.

## Casos de uso

E se você está se perguntando pra que criar uma tag customizada nativa do browser se o seu React/Angular já faz isso dentro do framework, vamos entender onde esses componentes podem te ajudar um bocado:

### Bibliotecas agnósticas

Se você também trabalha desenvolvendo libs que precisam rodar em diferentes tecnologias, vale a pena olhar com carinho pra uma abordagem baseada em web components.

Muitas libs do mercado já estão indo por esse caminho como o [Ionic](https://ionicframework.com/docs/components), o [Swiper](https://swiperjs.com), o [Material](https://material-web.dev), entre outros. A ideia aqui é criar a sua lib usando web components e criar wrappers pros frameworks que você quiser manter, enquanto suporta todos os outros. No caso do Swiper eles estão abandonando os wrappers também e indo pra uma abordagem full web component.

### Design Systems

Uma das coisas mais difíceis no desenvolvimento de design systems é conseguir manter uma base agnóstica que sobreviva ao longo do tempo sem sofrer com clones e adaptações.

Os devs da sua empresa usam Angular e a sua empresa compra uma outra empresa onde os devs usam React. Unificar as identidades visuais provavelmente vai girar em torno de clonar o Design System pra React, ou em casos mais doidos reescrever tudo pra Angular.

Já com web components seria basicamente criar wrappers pro react e ir substituindo os componentes mantendo a regra de negócio (quase) intacta.

### Micro Frontends

Eu continuo sendo do time contra Micro Frontends (fique à vontade pra me chamar pra bater um papo e me mostrar um case maneiro), mas respeito quem usa. Exemplo similar ao de Design Systems, MFEs geralmente envolvem a utilização de mais de um framework ao mesmo tempo.

E aqui, de novo, unificar os estilos entre diferentes times com diferentes frameworks é muuuito complicado. Às vezes eu navego em 3 telas do mesmo app e vejo 3 layouts diferentes, e é por conta dessa dificuldade de manter um padrão entre diferentes times com diferentes stacks de tecnologia em empresas gigantes.

Os Web Components se aplicariam muito bem nesse mesmo cenário tendo uma lib de componentes única entre os times.

## E como eu faço pra usar esse treco?

Bom, tem várias ferramentas por aí que vão te dar o mesmo resultado. Vale testar a que for melhor pro seu cenário, mas eu vou te dar algumas ideias:

Se o seu forte é Angular, o [Angular Elements](https://angular.dev/guide/elements) é a ferramenta oficial pra isso. Porém, eu te recomendo testar o [Lit](https://lit.dev) que tem uma sintaxe parecida mas é focado em Web Components. Outra opção é o [Stencyl](https://stenciljs.com/docs/getting-started), que é feito pela galera do Ionic.

Agora, se o seu forte é React, o suporte nativo só vai vir na v19 ([acompanhe essa thread aqui](https://github.com/facebook/react/issues/11347)), mas existem alguns wrappers pela comunidade que prometem o mesmo resultado. Outra opção, que eu recomendo fortemente, é o [preact](https://preactjs.com/guide/v10/web-components/) que é super leve, possui a mesma sintaxe e já tem suporte nativo.

E se você não está familiarizado com nenhum desses dois, vale fazer uns testes e ver qual você se adapta melhor.

## Opinião sobre o futuro do desenvolvimento front-end

Eu acredito fortemente que as bibliotecas que usamos serão mais focadas em web components e menos em frameworks. O Swiper e o Ionic são bons exemplo disso e têm evoluído bastante.

Isso permitiria à galera do Angular, por exemplo, usar vários componentes que hoje são exclusivos do React e vice-versa. Outro ganho é que as pessoas que hoje mantém libs para os dois frameworks poderiam concentrar os esforços em uma lib universal, usando o tempo livre pra tomar uma cerveja ou criar novas libs.

Eu não acho que valha a pena desenvolver uma aplicação comum com web components, porque os frameworks realmente aceleram o desenvolvimento e colocar mais uma camada no meio pode não ser muito inteligente. 

Porém, se você trabalha com libs, times cross, e/ou precisa ter uma base sólida de componentes, esse é o caminho. Eu tenho usado o preact onde vários sites de clientes usam os mesmos componentes e o resultado tem sido muito bom.

---

Se você curte o assunto e gostaria de ver mais posts desses por aqui, me avisa porque é algo que eu tenho gostado bastante de estudar, e acho que realmente vale a pena o investimento.

E se você não gostou de alguma coisa, ou tem alguma sugestão que possa fazer esse e os próximos artigos menores, lança aqui nos comentários também. Todo comentário é bem vindo e as críticas vão me ajudar a aprimorar os próximos posts 🙂