Microfrontends - uma visão geral e histórica sobre essa arquitetura.
Tags: javascript, programming, microfrontends, webcomponents
Published: 2022-07-08 15:53:18

Todo desenvolvedor tanto backend quanto frontend em algum momento da sua jornada nos últimos anos se deparou com o termo _Microfrontend_ como uma nova arquitetura para grandes aplicacões, e que daria autonomia e mais modularização do lado do frontend.

Geralmente olhamos para essa arquitetura pensando em como abordar ela e pouco entendemos seu histórico e sua evolução como arquitetura de software, a ideia com esse artigo é desbravar mais esses pontos.

## Microfrontends o que são?
É uma arquitetura para aplicações frontend no qual é uma extensão ao estilo de arquitetura de micro serviços, um componente de software que pode ser atualizado ou substituid0 de forma independente 

## Como surgiu?

### Evolução da arquitetura de software
![Imagem da arquitetura de software](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qn3vn9774a7rkt21a8rg.png)
Na história da evolução da arquitetura de software temos 3 pontos específicos.

1. Monolitico aquela aplicação MVC clássica onde temos todas as 3 camadas frontend, backend e acesso a dados em uma única estrutura de projeto com pastas específicas em cada uma dessas camadas em um único repositório.

2. Depois temos uma divisão clara entre código backend com seu acesso a dados e o código frontend muitas vezes também dividido em repositórios diferentes com times especializados em cada stack, isso começa a surgir com mais força depois de ter frameworks javascript MV whatever que resolviam e facilitavam o consumo e uso dos dados no lado do client/browser, angularjs é uma virada de chave importante aqui para os frontends pois a partir dele conseguiriamos essa autonomia 

3. Nessa segunda parte da história algo interessante foi acontecendo como as funcionalidades e os dados do lado do backend foram crescendo, o tamando do sistema também ia tomando grandes proporções, com isso da mesma forma os times para dar suporte a esse crescimento também precisavam aumentar.

4. Começamos a partir desse momento consumir um único backend em forma de serviços que precisavam atender a vários tipos de frontends como aplicações web e móveis.

5. Com todo esse contexto de crescimento de times e funcionalidades, automaticamente temos problemas crescendo na mesma proporção e velocidade e a solução encontrada foi usar uma arquitetura de microserviços.

6. Como podemos observar nesse último bloco a direita na imagem acima uma arquitetura de microserviços é pegar uma aplicação backend monolitica e dividir em pequenas APIs de serviços cada uma deve ter um escopo claro e responsabilidades específicas, cada microserviço deve ter um time especializado e dedicado a um domínio de conhecimento da aplicação.

### Mas onde entra os microfrontends nessa historia?
Imagina o seguinte, porque surgiram os microserviços? Muitas funcionalidades sendo inseridas na aplicação, time crescendo, problemas escalonando nas mesma proporcão, isso não é um cenário específico do backend, aplicações frontends monoliticas sofrem do mesmo problema. 

Com alguns pontos mais específicos para frontend:

1. Mais de um time envolvido para uma alteração de feature.
2. Times backend não tem o foco no cliente/usuário.
3. Testes no frontend costumam ser mais complexos, com isso as entregas em produção começam a ficar mais lentas.
4. Código mais acoplado.
5. Legados menos sustentáveis. 

Então porque não levar os mesmos principios utilizados para criacão de micro serviços para o frontend.

### Agora com microfrontends, como fica nossa arquitetura?

![Arquitetura de software com microfrontends](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdlrvm4d0otqj4thxm0s.png)

Estamos criando uma aplicação completamente dividida verticalmente, onde cada microfrontend está diretamente conectado com um microserviço, então cada fatia que a gente vê na imagem é uma feature autocontida entregue de ponta a ponta.

Com isso?

![Imagem com exemplo de microfrontends](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhrjbykipi9bnqdkrjkz.png)

temos uma aplicação de aparência única, mas composta por várias pequenas aplicações.

### Quais são os principios de Design compartilhados para Microserviços/Microfrontends?

1. Alta coesão
2. Autônoma
3. Centrada em um domínio de negócio
4. Times independentes
5. Resiliente
6. Observável
7. Automação

Vou passar por cada ponto, mas considerando apenas microfrontends.

**Alta coesão**
Cada microfrontend tem apenas uma única responsabilidade então que pode ser um produto ou feature.

**Autônoma**
Cada microfrontend deve ser publicado de forma independente e principalmente sem depender ou afetar os outros microfrontends

**Centrada em um domínio de negócio**
Cada microfrontend tem um foco e responde por um dominio de negócio dentro da organização, exemplo um microfrontend de extrato tem a responsabilidade de cuidar de extrato, a autenticação para acessar extrato tem que ficar a cargo de outro microfrontend que é responsável apenas por autenticação.

**Times independentes**
Um time focado no dominio do negócio fazendo a entrega do microfrontend responsável por esse domínio, o que é comum é tanto do lado do backend quanto do frontend ter um time responsável por essa feature de ponta a ponta.

**Resiliente**
Dentro de uma aplicação base ou geralmente chamada de shell onde podemos ter vários microfrontends trabalhando em conjunto, se um microfrontend falhar em seu carregamento não podemos impactar todas a aplicação, uma falha de um microfrontend não pode externalizar para fora dele.

**Observável**
Cada microfrontend tem seu próprio sistema de logging onde podemos analizar o que cada microfrontend está executando fornecendo alertas específicos para cada microfrontend deixando muito mais fácil a identificação.

**Automação**
Cada microfrontend é independente o suficiente para ter suas próprias ferramentas de automação de testes e deploys

Esses principios são compartilhados com os microfrontends, mas no cenário de microfrontends temos algumas caracteristicas mais específicas, que podem ser acrescentadas aos principios acima.

## Principios para microfrontends

1. Tecnologias agnósticas
2. Experiencia de usuario (UX)
3. Direcionados a microserviços

**Tecnólogias agnosticas**
Cada time responsável por um microfrontend pode ter total liberdade para escolher uma tecnologia que resolva aquele determinado problema no qual a stack se propõe a resolver, entenda que com isso você pode escolher alguma biblioteca ou framework específica para uma determinada parte da aplicação.

Mas como nem tudo são flores podemos ter alguns problemas que valem nossa atenção antes de iniciar um microfrontend agnóstico.

- Variáveis globais, principalmente tendo que lidar com legado.
- Conflito de versões entre bibliotecas e frameworks, podem haver conflitos internos entre frameworks libs iguais, mas de versões diferentes, na maioria dos casos apenas perceptível em tempo de execução da aplicação
- Devido a esses problemas encontrados podemos considerar uma stack para todos os microfrontends, perdemos um pouco de flexibildade em questão a escolha de tecnologia para se trabalhar, mas ganhamos em estabilidade, padronização de código, manutenção, problemas de conflito entre bibliotecas e frameworks

**User experience**
A experiência do usuário é outro principio chave que precisamos levar em consideração, pois não podemos levantar apenas vantagens dos microfrontends trazem para os times de desenvolvimento e deixar todos os problemas que isso pode acarretar para nosso cliente o consumidor final do nosso produto.

Quais os problemas que encontramos aqui para nossos usuários

- Performance
    - Agora temos N frameworks sendo carregados para o consumidor da nossa aplicação garantindo um bundle mais pesado para carregamento, mais processamento do lado browser, todo o nosso ganho como desenvolvedores pode trazer problemas consideráveis de performance para o usuário.

- Falta de padronização de interface
    - Carregar vários microfrontends podem trazer sérios problemas de experiência de usuário pois cada microfrontend pode entregar uma interface totalmente diferente da outra não criando homogeneidade que estamos esperando, quando queremos que uma aplicação com vários microfrontends tenha a aparência de uma unica aplicação ter essas diferenças de interface levanta vários problemas na experiência, por isso um bom design system e estratégias de modernização podem ser a chave para o sucesso nesse campo.

**Orientado a microserviços**
Outro principio importante é que eles são orientados a microserviços, cada microfrontend deve ter uma infraestrutura de micro serviços que de suporte a funcionalidade que está sendo entregue, em resumo os microfrontends deveriam em sua grande maioria ser uma extensão da arquitetura de micro serviços, que podem ser desde um api gateway ou um BFF

## Arquiteturas e abordagens para microfrontends

**Microapps**

![Microapss](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7l0jphmnrszn7rvbi8g.png)

São pequenas aplicações que podem ou não ser uma SPA que são distribuidas de forma completamente independente com um endereço na web e concentradas em um app em forma de links para essas aplicações, descrevendo dessa forma parece mais como um agregador de links com interface, mas eles geralmente compartilham componentes e elementos de interface através dessas aplicações com algum tipo de biblioteca ou até mesmo um CDN que traz a sensação de uniformidade em toda a aplicação, um exemplo seria compartilhar um menu entre as aplicações para dar a ilusão de um único app com comunicação entre os microfrontends podendo ser feitas através de query parameters ou até mesmo através de micro serviços em background.

Pontos negativos pensando em principios de design de microfrontends.

- User Experience
    - Cada microfrontend ocupa o espaço de toda a tela, toda a navegação baseia-se em atualização da página, não é possível ter microfrontends em partes específicas da tela.
    - Uma carga de banda considerável sendo usada, pensando em aplicações móveis toda nova navegação é carregado um framework, scripts, estilos que podem ser o mesmo mas não podem ser compartilhados nessa estrutura de microapps.

**Iframes**

![Exemplo de iframes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8uxlnyot2r6cevdx4yd.png)

Outra tecnologia web que pode ser utilizada para arquitetura de microfrontends, funcionam basicamente como microapps sendo disponibilizadas através de um endereço web em contexto e deploy completamente isolado, mas a vantagem em cima de microapps é poder ter vários microfrontends na mesma página melhorando a experiência de uma única aplicação.

Pontos negativos pensando em principios de design de microfrontends.

- Performance
    - Ter várias aplicações requer vários Iframes e isso tem um custo de processamento muito caro para o navegador, cada iframe é um ambiente completo e isso requer mais recursos computacionas que vão crescendo a cada utilização do iframe.
    - Cada Iframe também tem seu próprio framework sendo carregado de forma completa, se temos duas versões do angular identicas os recursos não são compartilhados, da mesma forma que com os microapps sendo assim aumentado ainda mais o uso de recursos dos dispositivos utilizados na navegação.

**Webcomponents**

![imagem de microfrontends com frameworks, react, angular, vue, sendo entregues como webcomponents](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvd5mmlutnjf3jn73rs2.jpeg)

É o conjunto de diferentes tecnologias que nos permite criar elementos personalizados e reutilizáveis, e toda sua funcionalidade encapsulada do restante do código.

Podemos ter o resultado parecido com o dos iframes com vários microfrontends em uma mesma página, mas com a vantagem de ter um ambiente de execução compartilhado entre os webcomponents, o conteúdo de cada um deles pode ser entregue por um servidor ou está dentro da própria aplicação na forma de webcomponents.

Outra vantagem é que não estão vinculados a nenhum tipo de framework javascript, construidos apenas com a tríade html, css e javascript.

Pontos negativos pensando em principios de design de microfrontends.

- Usando frameworks e bibliotecas se faz necessário cada webcomponent ter encapsulado o core deles, não sendo possível compartilhar eles em tempo de carregamento ou até mesmo de execução.

**Frameworks baseados em componentes**

![Frameworks de componentes como estratégia de isolar regras de negócio](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uf9zdcxisw7td8vsimz.png)

Levando em conta que podemos ter microfrontends como webcomponents, porque então não ter frameworks baseado em webcomponents orquestrando tudo isso, frameworks como angular, nextjs/react, vue.js são frameworks que podem nos fornece uma estratégia de criar webcomponents que podem ser praticamente um microfrontend entregando uma feature completamente isolada e com estratégias de lazy loading e ganhos de performance.

Pontos negativos pensando em principios de design de microfrontends.

- Não são feature autônomas, elas estão embarcadas dentro de todo o contexto da aplicação não sendo possível deploy e nem serem servidas de forma independente.
- Impossível trabalhar com tecnologias agnosticas pois a estratégia se baseia em trabalhar com algum framework ou bibliotecas específicas em todas as features.
- Apesar de ser uma abordagem que pode entregar uma certa autonomia não pode se considerada uma estratégia de microfrontend, exatamente devido ao processo de deploy não ser possível ser executado por feature, eu vou sempre fazer o deploy de toda a aplicação, apenas trouxe esse cenário para que possamos entender que não necessariamente precisamos pensar em microfrontends para todos cenários como se fosse uma bala de prata.

## Frameworks e plugins para arquiteturas de microfrontends
Temos algumas abordagens mais modernas para trabalhar com microfrontends atualmente, abaixo eu compartilho alguns links das propostas mais utilizadas atualmente, vale um estudo com cada um deles e entender o que faz mais sentido para o seu time.

**single-spa**
Framework para microfrontends que fornece suporte para reunir vários microfrontends em uma única single page application

**Module Federation**
é um plugin do webpack que permite trabalhar com microfrontends removendo uma carga de complexidade e com algum ganho de performance.

O ModuleFederationPlugin permite que uma compilação forneça ou consuma módulos com outras compilações independentes em tempo de execução, e com a grande vantagem de poder compartilhar depedências como o ponto forte desse plugin.

Bom era isso, se faltou algum ponto que era importante comentar deixa seu comentário que assim que possível eu atualizo esse material

### Referências: 

[https://micro-frontends.org/](https://micro-frontends.org/)
[https://martinfowler.com/articles/micro-frontends.html](https://martinfowler.com/articles/micro-frontends.html)
[https://tautorn.github.io/micro-frontends/](https://tautorn.github.io/micro-frontends/)
[https://single-spa.js.org/](https://single-spa.js.org/)
[https://webpack.js.org/plugins/module-federation-plugin/](https://webpack.js.org/plugins/module-federation-plugin/)
Kumar, Ajay. Micro Frontends Architecture: Introduction, Design, Techniques & Technology (p. 108). UNKNOWN. Edição do Kindle.