Executando verificação de segurança...
3

Web Components - Distribuindo funcionalidade com Micro-Frontends

Hello World

Há pouco tempo atrás, postei aqui no Tabnews sobre uma forma (não convencional) de compartilhar funcionalidade a partir de Web Components. A problemática era não só a distribuição, mas como reutilizar lógica sem necessáriamente reutilizar o html.

Ao reutilizar o html você precisa assumir que seu componente será um pouco mais complexo, já que além da lógica inerente contido nele, haverá uma lógica adicional para torná-lo minimamente dinâmico no que diz respeito à UI.

Naquele post, quis mostrar uma forma de desacoplar o html do js para que você possibilite compartilhar comportamentos complexos injetando dependências diminuindo drásticamente o bundle do seu Web Component e tornando-o mais flexível.


O Caso de Microfrontends

O caso dos microfrontends é um caso particular de distribuição de funcionalidade. Não é de escopo desse post explicar a motivação e o que é Microfrontends, deixo para um artigo que faz isso melhor que eu faria.

Meu objetivo é mostrar formas diferentes das conhecidas. Hoje, é possível fazer isso utilizando algum framework que automatize o processo, ou mesmo, utilizando a feature de module federation que alguns bundlers como o Webpack disponibilizam.

Diferentemente da necessidade do post anterior, onde a idéia era compartilhar comportamento mais genérico, no caso de Microfrontends a necessidade vai além, incluindo regras de negócio, chamadas de api's e integrações mais complexas, onde o objetivo não é a flexibilidade mas o reuso de uma experiência.

Nesse caso, carregar esta experiência em Runtime tem um grande benefício. Sua aplicação não precisa ser buildada toda vez que esta experiência atualiza. Isso favorece a reutilização e a rápida atualização, muito útil em momentos onde precisa evoluir e possui N aplicações utilizando sua experiência.

A estrutura

No post passado eu usei o meu repositório de mfes, onde eu utilizo o Parceljs como bundler para criar várias pastas de mfe's e gerar estáticos a partir dos seus arquivos.
A estrutura para o exmplo do swiper era essa:

mfes/
├── mfe-a
├── mfe-b
└── mfe-swiper/
    ├── app.ts
    ├── index.ts
    ├── index.css
    ├── index.pug
    └── page.pug

O parcel dá o output nestes arquivos:
https://mfe-jails.netlify.app/mfe-swiper/index.js
https://mfe-jails.netlify.app/mfe-swiper/index.css
https://mfe-jails.netlify.app/mfe-swiper/index.html
https://mfe-jails.netlify.app/mfe-swiper/page.html

No post passado eu dei ênfase apenas nos arquivos index.js e o index.css para reutilização de código no contexto de Web Components, eu reaproveitei esse repositório para o exemplo do post sobre Web Component.

Agora o meu foco é o link gerado que contém toda a funcionalidade standalone deste Web Component, ou seja, funcionando numa estrutura de página html convencional. Portanto se navegar neste último link, verá o funcionamento do Web Component em sua totalidade.

O Problema

Eu não costumo utilizar frameworks nos meus projetos pessoais. Acho inclusive super complexo a maneira como se contrói micro-frontends utilizando os frameworks e além disso, são casos muito específicos onde utilizo.

Uma das minhas maiores queixas com relação ao mundo front-end hoje é com relação ao over-engineering, muita complexidade desnecessária.

Reclamar é fácil, mas qual a sugestão?

O jeito mais simples de se reutilizar funcionalidades é o uso de <iframe />. O iframe não é em si uma solução ruim, ele apenas possui algumas limitações. Uma delas é a limitação de altura automática. As maneiras de se contornar isso via iframe são desastrosas.

O browser funciona da mesma maneira para qualquer tipo de aplicação web. Ele depende de um html, scripts carregados / executados, e css. Essa tríade, simples, é o que compõe a aplicação Web, não importa o quão complexo o framework é. Tem assets inclusos nessa dinâmica também como: Fontes, Imagens, Svg's, mas no final, são arquivos externos carregados utilizando elementos html no DOM.

Com isso, tenho utilizado uma técnica mais simples. Eu carrego a página contendo minha aplicação externa via javascript, que contém todo o html e as tags que apontam para os assets dependentes, e monto na minha aplicação atual.

Eu queria algo como o iframe, onde eu apontasse um endereço html e ele embedasse na minha aplicação.

A Solução

Construí essa interface agnóstica que faz algo parecido com o Iframe. Ele faz o fetch de uma página e internamente algumas mágicas para resgatar o script, css e adicionar na minha página atual.

O código fica mais ou menos assim:

import { mfe } from 'jails.std/mfe'

const helloworld = document.querySelector('#hello-world')
const microfrontend = mfe()

microfrontend.render( 
    helloworld,
    'https://mfe-jails.netlify.app/mfe-hello-world/page.html'
)

É possível ver o uso e funcionamento aqui: https://stackblitz.com/edit/jails-mfe-xkf9e5at?file=index.ts

Conclusão

Tem funcionado muito bem para mim especialmente se não utilizo nenhum framework que acaba fazendo mágica demais na aplicação, ou de alguma forma sequestra a DOM tree.

Essa interface está nesse repo: https://github.com/jails-org/Std
Que é um repo de funcionalidades mais vanilla, bibliotecas padrão que utilizo nos meus projetos.

Conforme vai pesquisando, vai aprendendo que não foi a única pessoa que usa certas técnicas. O Turbolinks da galera do Rails utilizava há um tempo atrás, mas para a aplicação inteira, para construir páginas no modelo multi-pages, mas com sensação de Single Page Apps.

No meu caso, acabei utilizando uma idéia similiar em escopo menor.

Importante: É preciso habilitar o CORS para os endereços que você deseja compartilhar. Por questões de segurança, via javascript, você não consegue carregar conteúdos html de domínios diferentes.

É isso, no futuro posso trazer casos um pouco mais complexos que este se for de interesse para alguém como este abaixo:


Tractor - Microfrontend


Até o próximo!
Obrigado

Carregando publicação patrocinada...