React

Arquitetura de Frontend Modular: Micro Frontends na prática com Module Federation

Arquitetura de Frontend Modular: Micro Frontends na prática com Module Federation

Introdução: o desafio da escala em grandes frontends

À medida que aplicações front-end crescem, aumentam também os desafios: múltiplas equipes atuando em paralelo, deploys travados por dependências entre módulos, e código cada vez mais difícil de manter.

Foi nesse cenário que surgiram os Micro Frontends — uma abordagem que aplica os princípios de microsserviços ao frontend. E uma das formas mais eficazes de implementá-los hoje é com o Module Federation, recurso introduzido no Webpack 5.

Neste artigo, você vai entender como funciona essa arquitetura na prática, com exemplos, boas práticas e armadilhas para evitar.


O que são Micro Frontends?

Micro Frontends são uma forma de dividir uma aplicação frontend em múltiplos projetos independentes, onde cada um pode ser desenvolvido, testado e implantado separadamente.

Benefícios:

  • Autonomia entre times

  • Deploys independentes

  • Redução de conflitos de merge

  • Melhor organização de código


Module Federation: a cola entre os Micro Frontends

O Module Federation é um recurso do Webpack que permite que uma aplicação carregue módulos de outra em tempo de execução. Isso resolve um dos grandes problemas: como compartilhar código entre projetos diferentes sem acoplamento direto.

Conceitos-chave

  • Host (Container): o app principal que consome os módulos remotos.

  • Remote: o app que expõe módulos a outros.

  • Exposes: define o que o remote disponibiliza.

  • Remotes: define o que o host consome.


Exemplo prático: aplicação de e-commerce

Imagine uma aplicação de e-commerce com dois módulos:

  • app-catalog: responsável pela vitrine de produtos

  • app-cart: responsável pelo carrinho de compras

1. Configurando o app-catalog

// webpack.config.js
new ModuleFederationPlugin({
  name: "catalog",
  filename: "remoteEntry.js",
  exposes: {
    './ProductList': './src/components/ProductList',
  },
  shared: { react: { singleton: true }, 'react-dom': { singleton: true } }
})

2. Configurando o app-cart como Host

// webpack.config.js
new ModuleFederationPlugin({
  name: "cart",
  remotes: {
    catalog: "catalog@http://localhost:3001/remoteEntry.js",
  },
  shared: { react: { singleton: true }, 'react-dom': { singleton: true } }
})

3. Importando o componente remoto

// app-cart/src/App.js
const ProductList = React.lazy(() => import('catalog/ProductList'));
 
function App() {
  return (
    <React.Suspense fallback={<div>Carregando...</div>}>
      <ProductList />
    </React.Suspense>
  );
}

Boas práticas com Micro Frontends

  • Use versões compatíveis de bibliotecas compartilhadas para evitar conflitos de dependências.

  • Isolar estados e rotas entre os micro frontends.

  • Padronize a comunicação entre módulos, com eventos ou stores globais bem definidos.

  • Evite sobreposição de estilos — use CSS Modules, Tailwind ou encapsulamento com Shadow DOM.


Armadilhas comuns (e como evitá-las)

  1. Latência no carregamento dos remotes
    → Use fallback com React.Suspense e carregamento assíncrono inteligente.

  2. Problemas com dependências duplicadas
    → Configure corretamente o shared no Module Federation.

  3. Gerenciamento de estado global acoplado
    → Prefira estratégias de isolamento ou bibliotecas como Redux Toolkit, Recoil ou Zustand com contextos isolados.

  4. Deploys inconsistentes
    → Use versionamento semântico dos remotes e CDN para cache controlado.


Conclusão: modularize com responsabilidade

Micro Frontends com Module Federation trazem escalabilidade e autonomia para grandes aplicações frontend — mas exigem planejamento, padronização e boas práticas.

Experimente modularizar uma parte do seu app atual e compartilhe sua experiência! Compartilhe com o time e continue explorando o tema.