Voltar para a página inicial

Micro Frontends: Como dividir para conquistar e o poder do Module Federation

Descubra como a arquitetura de Micro Frontends resolve problemas de escalabilidade em grandes aplicações, aprenda a fatiar por domínio e veja como usar o Module Federation na prática, além de entender os reais desafios dessa abordagem.

Por Allison Verdam07 de agosto de 20266 mins de leitura
javascriptReactarquiteturamicro frontendsmodule federationfrontendescalabilidade

Micro Frontends: Como dividir para conquistar e o poder do Module Federation

Hoje estarei falando um pouco sobre a arquitetura de Micro Frontends, um padrão que vem ganhando muita força para resolver gargalos de escalabilidade em times grandes, e dando alguns exemplos de como implementá-la na prática utilizando Module Federation, além de pontuar os desafios reais dessa abordagem.

  • Micro Frontends aplicam os conceitos de microsserviços no navegador, dividindo a aplicação em fatias independentes por domínio de negócio.

  • Eles permitem que múltiplos times trabalhem em repositórios separados, usando até tecnologias diferentes, e façam deploys de forma independente.

  • O Module Federation (introduzido no Webpack 5 e agora presente em bundlers modernos como Rspack e Vite) é o divisor de águas que tornou a orquestração no cliente muito mais eficiente.

O problema do front-monólito

Quem nunca trabalhou em uma aplicação SPA (Single Page Application) que começou pequena, ágil e divertida de mexer, mas com o passar dos anos virou um monstro? Em aplicações front-end monolíticas de grande porte, os problemas começam a se acumular rapidamente.

O tempo de build dispara (às vezes passando de dezenas de minutos). Qualquer mudança simples, como ajustar a cor de um botão ou corrigir um bug de CSS no carrinho de compras, exige o deploy da aplicação inteira. Além disso, os times começam a pisar no calo uns dos outros: conflitos de merge diários no package.json, testes quebrando por efeitos colaterais em outras partes do sistema e uma lentidão generalizada na entrega de valor.

Foi para curar essa dor de escala organizacional e técnica que nasceram os Micro Frontends.

O que são (fatias por domínio, não por camada)

A ideia central é simples: pegar sua aplicação gigante e quebrá-la em pedaços menores e independentes. No entanto, o grande erro de quem começa a estudar o tema é tentar fatiar por componentes genéricos (ex: criar um micro frontend só para o Header ou só para um botão).

A regra de ouro dos Micro Frontends é o fatiamento vertical por domínio de negócio, assim como fazemos em microsserviços no backend.

Por exemplo, em um e-commerce, você teria:

  • Um Micro Frontend para o Catálogo de Produtos (responsável pela listagem e busca).

  • Um Micro Frontend para o Checkout (carrinho, pagamento, frete).

  • Um Micro Frontend para o Perfil do Usuário (histórico de pedidos, dados pessoais).

Dessa forma, o time de Checkout pode lançar uma feature nova de pagamento PIX sem correr o risco de quebrar a página de listagem de produtos.

Onde compor: cliente, servidor ou build?

Existem várias formas de juntar esses pedaços isolados para que o usuário final veja apenas uma única aplicação coesa. A composição pode acontecer em três momentos diferentes:

  • No momento do Build: Publicando cada pedaço como um pacote NPM privado. Problema: Perde-se a vantagem do deploy independente. Se o time de Checkout atualizar o pacote, a aplicação "host" (casca) precisa ser recompilada e redeployada.

  • No Servidor (Server-side): Usando técnicas como Server Side Includes (SSI), Edge Side Includes (ESI) em CDNs, ou roteamento via Next.js/Nuxt. Ótimo para SEO, mas a configuração de infraestrutura pode ficar bem complexa.

  • No Cliente (Client-side): A composição acontece direto no navegador. Historicamente, isso era feito com iframes (isolamento perfeito, mas péssima usabilidade e performance) ou Web Components. Hoje, a abordagem moderna e dominante é o uso de importações dinâmicas via Module Federation.

Module Federation na prática

O Module Federation mudou o jogo da composição no cliente. Ele permite que uma aplicação JavaScript carregue dinamicamente o código de outra aplicação em tempo de execução (runtime), compartilhando dependências para não baixar a mesma biblioteca duas vezes.

Veja um exemplo simplificado de como expomos o nosso Micro Frontend de Checkout (App Remoto) configurando o webpack.config.js:

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "checkoutApp",
      filename: "remoteEntry.js", // O arquivo que o app casca vai ler
      exposes: {
        "./Pagamento": "./src/components/Pagamento", // Expõe o componente de pagamento
      },
      shared: { react: { singleton: true }, "react-dom": { singleton: true } },
    }),
  ],
};

E na nossa aplicação principal (App Host), nós consumimos esse módulo dinamicamente. Caso o React já tenha sido carregado pelo Host, o checkoutApp usa a versão em memória, economizando banda e mantendo o contexto do React intacto.

Os desafios reais (nem tudo são flores)

Adotar Micro Frontends resolve o gargalo dos times, mas transfere a complexidade para a arquitetura e operação. Antes de mergulhar de cabeça, você precisa dominar estes quatro pilares:

  • Dependências: O Module Federation ajuda, mas gerenciar versões de bibliotecas (como React, Lodash, ou ferramentas de UI) entre vários times exige contratos rígidos. Se um micro frontend exige React 19 e outro exige React 17, a aplicação pode quebrar ou ficar super pesada.

  • Consistência Visual: Como garantir que a aplicação não pareça um "Frankenstein"? É obrigatório ter um Design System forte e versionado, para que botões, tipografias e formulários tenham o mesmo visual independente de qual time os desenvolveu.

  • Comunicação: Micro frontends devem ser o mais isolados possível, mas às vezes eles precisam conversar (ex: o Catálogo avisa o Checkout que um item foi adicionado). A regra é usar abordagens reativas desacopladas (Custom Events do navegador ou uma camada global de pub/sub mínima), nunca passando funções complexas via propriedades inter-aplicações.

  • Operação e Debug: Implementar CI/CD para 10 repositórios diferentes dá trabalho. Além disso, rastrear um bug que começa na casca, passa pela rota do catálogo e quebra no checkout exige ferramentas avançadas de monitoramento, logs centralizados (como Sentry) e Error Boundaries no React para impedir que o erro de um micro frontend derrube a tela inteira.

Boas práticas e quando NÃO usar

O isolamento deve ser respeitado a todo custo. Isole seu CSS (CSS Modules, Styled Components ou Tailwind com prefixos) para que um micro frontend não sobrescreva a cor do outro. Sempre trate falhas de rede no carregamento dos remotos utilizando fallbacks visuais (como o Suspense do React).

Quando NÃO usar?
Micro Frontend não é bala de prata. Se você tem um time pequeno (menos de 30 desenvolvedores no front-end), atua num produto único ou está em uma startup ainda validando o modelo de negócios, fique no monólito. A complexidade de orquestrar repositórios, CI/CDs e rotas dinâmicas vai atrasar suas entregas em vez de acelerá-las.

Conclusões finais

A arquitetura de Micro Frontends é incrivelmente poderosa para empresas que já atingiram a barreira da escala no front-end. Com a chegada do Module Federation, a barreira técnica para orquestrar essas aplicações no cliente caiu drasticamente, oferecendo performance e excelente experiência de desenvolvimento.

Ao meu ver a principal vantagem é a autonomia dos times, permitindo que cada squad foque em seu próprio domínio de negócio com deploys ágeis e independentes.

Espero que você tenha aproveitado alguma coisa do conteúdo apresentado.

Aqui no blog tem posts falando sobre outros padrões de arquitetura e design patterns, da uma olhada.

Acho que é isso, se tiver ficado com alguma dúvida ou tenha alguma sugestão escreve aqui nos comentários.

Comentários