Todos esses anos, você, o desenvolvedor front-end, escreveu monólitos, embora tenha entendido que esse era um mau hábito. Você dividiu seu código em componentes, usou
require
ou
import
e definiu pacotes npm no package.json ou gerou repositórios git em seu projeto, mas, de qualquer maneira, você escreveu um monólito.
É hora de mudar de posição.
Por que seu código pode ser considerado um monólito?
Por natureza, todos os aplicativos de front-end são monolíticos - exceto os que implementam micro-front-end. O motivo é que você está desenvolvendo usando a biblioteca React, e duas equipes estão fazendo o trabalho. Ambos devem usar a mesma versão do React e manter-se atualizado com as atualizações, o que significa que eles resolverão invariavelmente os conflitos com a fusão do código. Eles não são completamente independentes um do outro na base de código. Eles provavelmente todos usam o mesmo repositório e um sistema de construção. Os microsserviços podem economizar em aplicativos monolíticos! Mas como assim? Afinal, eles são para o back-end! * surpresa incrível *
O que são microsserviços?
Em termos simples, os microsserviços são uma técnica de desenvolvimento que permite que os desenvolvedores façam entregas independentes de funcionalidade (versões) para diferentes partes da plataforma e, ao mesmo tempo, as versões não se quebram. Suprimentos independentes lhes permitem coletar serviços isolados ou pouco acoplados. Existem várias regras que tornam essa arquitetura mais robusta. Resumidamente, eles podem ser definidos da seguinte forma: cada serviço deve ser pequeno e executar apenas uma tarefa. Portanto, a equipe que trabalha nela também deve ser pequena. Qual o tamanho de um projeto e equipe,
explica James Lewis e Martin Fowler:
Os desenvolvedores que interagem com os microsserviços nomeiam tamanhos diferentes. Os maiores deles atendem à estratégia da equipe de duas pizzas da Amazon - não mais que 10 a 12 pessoas. O polo reverso - equipes de 5 a 6 pessoas, onde cada uma suporta um serviço.
Aqui está um diagrama explicando a diferença entre um monólito e microsserviços:

Pode ser visto no diagrama que cada serviço no sistema de microsserviço é um aplicativo separado, exceto para a interface do usuário - ele continua sendo um todo! Quando todos os serviços são suportados por uma equipe, é grande o risco de que, à medida que a empresa cresce, a equipe de front-end não mantenha mais a interface do usuário. Essa é a vulnerabilidade dessa arquitetura.

Arquitetura pode trazer problemas organizacionais. Suponha que a empresa tenha crescido e adotado uma metodologia de desenvolvimento flexível (estou falando do Agile). Eles exigem pequenas equipes multifuncionais. Obviamente, em nosso exemplo abstrato, os gerentes começarão a separar as tarefas do front-end e do back-end, e as equipes multifuncionais não serão realmente multifuncionais. E todos os esforços serão em vão: a equipe pode parecer flexível, mas na verdade será bastante dividida. Gerenciar uma equipe assim não é para os fracos de coração. Em cada reunião, haverá uma pergunta: há tarefas de front-end suficientes, tarefas de back-end suficientes no sprint? Para resolver esses e muitos outros problemas, há alguns anos surgiu a idéia de microfronte, que rapidamente ganhou popularidade.
Solução para o problema: microfrotos
A solução parece bastante óbvia, porque princípios semelhantes foram aplicados com sucesso no trabalho em serviços de back-end: dividir um front-end monolítico em pequenos fragmentos de interface do usuário. No entanto, a interface do usuário não é muito parecida com os serviços - é uma interface entre o usuário final e o produto, deve ser cuidadosa e sistemática. Além disso, na era dos aplicativos de página única, aplicativos inteiros são lançados por meio de um navegador no lado do cliente. Não são mais arquivos HTML simples, são componentes complexos que podem conter várias UIs e lógica de negócios. Agora, talvez, seja necessário definir microfrontas.
O princípio dos microfrontos: a apresentação de um site ou aplicativo da web como um conjunto de funções pelas quais as equipes independentes são responsáveis. Cada equipe tem sua própria missão, seu próprio campo de trabalho no qual se especializa. A equipe é multifuncional e desenvolve
todo o ciclo - do banco de dados à interface do usuário ( micro-fontend.org ).
Minha experiência atual mostra que, para muitas empresas, pode ser difícil aceitar a arquitetura proposta acima. Para outros, a carga do código antigo não permite mudar para a nova arquitetura. Portanto, é necessária uma maneira de migração mais suave, fácil e confiável. Tendo examinado a arquitetura em mais detalhes, tentarei oferecer minha visão para resolver o problema. Antes de se aprofundar nos detalhes, familiarize-se com a terminologia.
Estrutura geral e mais algumas terminologiasImagine que dividimos a estrutura de um aplicativo monolítico verticalmente, por funções de negócios. Obteremos várias aplicações menores com a mesma estrutura que a aplicação monolítica. Mas se adicionarmos um aplicativo especial sobre esses pequenos aplicativos monolíticos, os usuários irão interagir com ele. Por sua vez, integrará a interface do usuário desses pequenos aplicativos. Chamamos esse nível de link, porque ele pega os elementos da interface do usuário de cada microsserviço e os combina em uma única interface - essa é a implementação mais direta do microfronte. * admiração sincera *

Para tornar mais claro, abaixo, chamarei cada aplicativo monolítico pequeno de
micro aplicativo, já que esses não são apenas microsserviços, mas aplicativos independentes - cada um deles possui elementos de interface do usuário e cada um deles representa uma função de negócios completa. Como você sabe, o ecossistema front-end de hoje é muito diversificado e pode ser bastante complexo. E soluções simples e óbvias podem não ser apropriadas no processo de implementação do produto.
Problemas a serem resolvidos
Quando a ideia deste artigo nasceu, iniciei um tópico no Reddit para discuti-lo. Graças aos membros da comunidade e seus comentários, posso listar os problemas que precisam ser abordados.
Problema número 1: obtenha um comportamento consistente e consistente a partir da interface do usuário quando tivermos vários aplicativos micro completamente autônomos
Não existe panacéia, mas existe a ideia de criar uma biblioteca de interface do usuário comum, que também seria um micro aplicativo independente. Nesse caso, todos os outros micro aplicativos deverão depender dessa biblioteca de interface do usuário. E isso mata sua independência.
Outra opção é criar
variáveis CSS comuns no nível raiz. A vantagem desta solução é que obtemos um tema personalizado global para todos os aplicativos.
Ou podemos tornar variáveis e impurezas do SASS comuns a todas as equipes. Entre as desvantagens dessa abordagem, estão a implementação repetida dos elementos da interface do usuário e a necessidade de verificação constante do design de elementos semelhantes em todas as micro aplicações.
Problema número 2: verifique se uma equipe não reescreve o CSS de outra equipe
Primeiro, você pode limitar o escopo do CSS usando seletores formados pelo nome da microaplicação. Ao colocar essa restrição na camada intermediária, você pode reduzir o tempo geral de desenvolvimento, mas, ao mesmo tempo, a responsabilidade da camada intermediária aumentará.
Em segundo lugar, você pode fazer com que cada
microaplicação se torne um
componente da web personalizado . A vantagem dessa abordagem é que o navegador lida com a restrição. No entanto, tudo tem um preço: com o Shadow DOM, é quase impossível renderizar no lado do servidor. Além disso, os elementos personalizados
não são 100%
suportados pelos navegadores - especialmente se você precisar do suporte do IE.
Problema número 3: tornar as informações globais comuns a diferentes microaplicações
Esse problema é um dos mais comuns, mas é resolvido com bastante facilidade. O HTML5 tem uma funcionalidade bastante poderosa, quase inexplorada pela maioria dos desenvolvedores de front-end.
Um desses recursos são os eventos personalizados que permitem tornar as informações comuns aos micro aplicativos.
Uma implementação pub-sub ou T39 também pode ajudar. Se você precisar de um manipulador de estado global mais sutil, poderá implementar um pequeno Redux geral - isso fornece uma arquitetura mais responsiva.
Problema número 4: se todas as micro aplicações são autônomas, como realizar o roteamento no lado do cliente?
A solução para o problema depende da implementação. Todas as principais estruturas modernas possuem poderosos mecanismos de roteamento do lado do cliente usando o status do histórico do navegador. O problema é qual aplicativo é responsável pela rota atual e quando exatamente.
Minha abordagem pragmática é criar um roteador de cliente comum, responsável apenas pelas rotas de nível superior, e o restante está à mercê das micro-aplicações correspondentes. Suponha que tenhamos uma definição de rota
/content/:id.
O roteador comum resolverá a parte c
/content
e a rota resolvida será passada para o ContentMicroApp. O ContentMicroApp é um servidor independente que será chamado apenas com
/:id
.
Problema número 5: precisamos realmente de SSR (renderização no servidor), é possível ao usar microfrontos?
A renderização no servidor não é fácil. Se você deseja agrupar microaplicativos usando iframes, esqueça a renderização no servidor. Da mesma forma, os componentes da Web para ligação não são mais fortes que iframes. No entanto, se cada um dos micro aplicativos for capaz de renderizar o conteúdo do servidor, a camada de conexão será responsável apenas pela combinação de fragmentos HTML no lado do servidor.
Problema 6: “A integração com o ambiente existente é necessária como o ar! Como fazer isso?
Para integração com sistemas existentes, quero descrever minha visão, que chamo de "
implementação gradual ".
Antes de tudo, devemos implementar a camada de middleware para que ela tenha a funcionalidade de um servidor proxy transparente. Depois disso, podemos definir o sistema existente como um
microaplicativo (
LegacyMicroApp ) declarando uma rota especial para ele. Todo o tráfego que atingir o nível de conexão terá um proxy transparente para o sistema existente, pois ainda não temos outros micro aplicativos.
O próximo passo é a implementação gradual. Vamos pegar um pequeno pedaço do
LegacyMicroApp , removendo a navegação principal e substituindo-a por uma dependência. Essa dependência é um micro aplicativo implementado usando a nova tecnologia brilhante, NavigationMicroApp.
Agora, o
LegacyMicroApp interceptará todas as rotas através da dependência NavigationMicroApp e a processará internamente.
Da mesma forma, refazeremos o rodapé.
Portanto, continuaremos a morder um pedaço do
LegacyMicroApp até que não haja mais nada.
Problema número 7: orquestrar o lado do cliente para que você não precise recarregar a página toda vez
A camada de middleware resolve problemas no lado do cliente, mas não no lado do servidor. No lado do cliente, ao fazer o download de um único HTML, não podemos carregar partes individuais ao alterar URLs. Portanto, precisamos de um mecanismo que carregue fragmentos assincronamente. O problema é que esses fragmentos podem ter dependências e precisam ser resolvidos no lado do cliente. Isso significa que a solução de microfrontend deve oferecer um mecanismo para carregar microaplicações e implementar injeção de dependência.
Os problemas listados acima podem ser combinados nos seguintes tópicos:
Lado do cliente- Orquestração
- Encaminhamento
- Micro Isolamento
- Interação de aplicativo
- Micro-aplicativos da UI da unidade
Lado do servidor- Renderização do servidor
- Encaminhamento
- Gerenciamento de Dependências
Arquitetura flexível e poderosa, mas simples
Por isso, valeu a pena suportar o início do artigo! Os principais elementos e requisitos da arquitetura de micro-fontes finalmente começaram a surgir;)
Guiado pelos requisitos e preocupações, comecei a desenvolver uma solução chamada
microfe . * antecipação de feedback *
Aqui vou descrever a arquitetura do projeto, descrevendo brevemente seus principais componentes.
A maneira mais fácil de iniciar é do lado do cliente, que possui três estruturas principais separadas:
AppsManager, Loader, Router e também uma outra,
MicroAppStore .
AppsManagerO AppsManager é o núcleo da orquestração de micro aplicativos do lado do cliente. O principal objetivo do AppsManager é criar uma árvore de dependência. Depois que todas as dependências são resolvidas, o AppsManager inicia o microaplicativo.
CarregadorOutra parte crucial da orquestração do lado do cliente é o Loader. Ele é responsável por baixar aplicativos para o lado do cliente.
RoteadorPara executar o roteamento do lado do cliente, implementei o roteador em microfe. Ao contrário dos roteadores convencionais do lado do cliente, o roteador microfe possui funcionalidade limitada. Não processa páginas, mas micro aplicações. Digamos que tenhamos URL
/content/detail/13
e ContentMicroApp. Nesse caso, o roteador microfe processará a URL para
/content/*
e chamará a parte ContentMicroApp
/detail/13
.
MicroappporePara resolver a interação do cliente entre micro aplicativos, implementei o MicroAppStore em microfe. Ele tem a mesma funcionalidade da biblioteca Redux, mas com uma ressalva: é mais flexível com relação à modificação de dados assíncrona e reducer'a declaração.
***
O lado do servidor é talvez um pouco mais complicado de implementar, mas possui uma estrutura mais simples. Consiste em duas partes principais - StitchingServer e MicroAppServer.
Microappserver

A menor funcionalidade possível do MicroAppServer pode ser expressa como: init e serve.
Quando o MicroAppServer é inicializado, a primeira coisa a fazer é chamar o SticthingServer e registrar um terminal com o microaplicativo anunciado. Ele define as dependências, tipos e URLs do esquema MicroAppServer. Eu acho que falar sobre servir é desnecessário - não há nada interessante aqui.
Servidor de costura

O StitchingServer permite registrar um terminal com o MicroAppServers. Quando o MicroAppServer se registra no StichingServer, o StichingServer registra a declaração MicroAppServer.
Posteriormente, o StitchingServer usa o anúncio para resolver o MicroAppServices a partir do URL solicitado.
Depois de permitir o MicroAppServer e todas as suas dependências, a URL pública correspondente aparecerá nos nomes de todos os caminhos correspondentes em CSS, JS e HTML. Uma etapa adicional é adicionar um prefixo exclusivo do MicroAppServer aos seletores de CSS para evitar conflitos entre micro aplicativos no lado do cliente.
Então a principal tarefa do StitchingServer entra em cena: o layout de todas as partes recebidas e o retorno de uma página HTML inteira.
Algumas palavras sobre outras implementações
Mesmo antes do termo microfrontend aparecer em 2016, muitas grandes empresas tentaram resolver problemas semelhantes - por exemplo, o Facebook com o
BigPipe .
Agora a ideia está ganhando força. Empresas de todos os tamanhos estão interessadas neste tópico, investindo tempo e dinheiro nele. Por exemplo, Zalando forneceu o código-fonte aberto para sua solução
Project Mosaic . Posso dizer que microfe e Project Mosaic seguem abordagens semelhantes, mas com algumas diferenças fundamentais. Se a microfe recorrer ao roteamento totalmente descentralizado para tornar cada microaplicação mais independente, o Project Mosaic prefere o roteamento centralizado e a definição de padrão para cada rota. A propósito, o Project Mosaic facilita a realização de testes AB e geração dinâmica de modelos em tempo real.
Existem outras abordagens, em particular, o uso de iframs como uma camada de conexão - obviamente, não no lado do servidor, mas no lado do cliente. Essa é uma solução muito simples que não requer uma estrutura especial de servidor e envolvimento do DevOps. Ele pode ser implementado pela equipe de front-end de forma independente, o que significa que cria menos problemas organizacionais para a empresa e custa menos.
Ainda existe uma estrutura de
spa único . O projeto baseia-se em convenções de nomenclatura para cada aplicativo para permitir e baixar micro aplicativos. Fácil de entender a ideia e seguir padrões. Portanto, a estrutura pode ser útil para conhecer e experimentar o sistema em seu ambiente local. O ponto negativo do projeto é que você precisa criar cada micro aplicativo de maneira estritamente definida - caso contrário, a estrutura pode não aceitá-lo.
Conclusão (e links)
Penso que, com o tempo, o tópico sobre microfrontas será considerado em mais detalhes. Se começar a atrair a atenção de mais e mais empresas, esse conceito se tornará o método de desenvolvimento padrão em grandes equipes. Será útil para cada desenvolvedor front-end se familiarizar com essa arquitetura em um futuro próximo e obter uma experiência valiosa ao trabalhar com ela.
servidor de registro de aplicativo micro femicro infraestrutura de front-end