R
Interview Deckreact · next.js · senior/staff
0·0·122
Microfrontend

Micro-Frontends — Module Federation

Dividir o frontend em apps independentes com deploy separado. Module Federation no Webpack/Vite.

Micro-frontends dividem um app grande em apps menores independentes, cada um com seu próprio deploy, bundle e time. Module Federation (Webpack 5 / Vite) permite que apps exponham e consumam módulos remotamente em runtime — sem precisar rebuildar o host. Shell app (host) carrega remote apps dinamicamente. Single-SPA é uma alternativa de orquestração.

Problema
App monolítico de frontend que 5 times editam simultaneamente. Deploy de qualquer feature exige testar e deployar o app inteiro. Times ficam esperando uns pelos outros para fazer release.
Solução
Shell app (host) que define layout e navegação. Remote apps (team-a, team-b) que expõem componentes ou rotas via Module Federation. Cada remote faz deploy independente. O shell carrega remotes em runtime pelo URL do manifesto.
Tip
Micro-frontends têm custo alto: duplicação de React no bundle, complexidade de integração, compartilhamento de estado entre apps. Só justifica quando o problema de coordenação de times é real e documentado. Para a maioria dos apps, monorepo com módulos resolve o problema sem a complexidade.
// webpack.config.js do Shell (host)
new ModuleFederationPlugin({
  name: 'shell',
  remotes: {
    teamA: 'teamA@https://team-a.example.com/remoteEntry.js',
    teamB: 'teamB@https://team-b.example.com/remoteEntry.js',
  },
  shared: {
    react: { singleton: true, requiredVersion: '^18' },
    'react-dom': { singleton: true, requiredVersion: '^18' },
  },
})

// webpack.config.js do Remote (team-a)
new ModuleFederationPlugin({
  name: 'teamA',
  filename: 'remoteEntry.js',
  exposes: {
    './CheckoutPage': './src/pages/CheckoutPage',
    './CartWidget':   './src/components/CartWidget',
  },
  shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
})

// No shell: carregar remote dinamicamente
const CheckoutPage = React.lazy(() => import('teamA/CheckoutPage'))

function App() {
  return (
    <Suspense fallback={<Spinner />}>
      <CheckoutPage />
    </Suspense>
  )
}
Q.Diferença entre Module Federation e iframes?
A.iframes: isolamento total (CSS, JS não vazam), mas integração ruim (comunicação via postMessage, performance, acessibilidade). Module Federation: apps compartilham o mesmo DOM e podem compartilhar libs (React singleton), integração nativa mas sem isolamento. Iframes para conteúdo realmente isolado (widgets, third-party).
Q.Como compartilhar estado entre micro-frontends?
A.Evitar estado compartilhado muda o design. Opções: 1) Custom events (window.dispatchEvent) — simples mas frágil. 2) Shared store (Zustand singleton compartilhado). 3) URL como fonte de verdade (query params). 4) Backend-driven state (polling/websocket). A melhor solução é não precisar compartilhar.
Q.Como garantir que versões de React não conflitem?
A.Module Federation: declarar React e ReactDOM como singleton: true e requiredVersion em shared. Isso garante que apenas uma instância de React roda, mesmo com múltiplos remotes. Sem singleton, cada remote carrega sua própria cópia e hooks quebram (viola Rules of Hooks entre instâncias).
65/122← →