Feito de partes. Visto como um todo.
Junte micro-frontends de qualquer framework numa página só, sem configuração de build no host.
Medido no Chromium com rede Slow 4G, mediana de 7 visitas. Método.


Cada equipe publica o próprio pedaço da página com vite build. O host recebe a URL de cada pedaço e monta tudo no navegador. Por que o vitral explica quando usar e quando não usar.
Registre a URL do vitral.json de cada remote e renderize. Nenhum plugin no build do host.
import { configure } from 'vitral'
import { Remote } from 'vitral/react'
configure({
remotes: { carrinho: 'https://cdn.empresa.com/carrinho/vitral.json' },
})
export const App = () => <Remote name="carrinho" props={{ userId: 42 }} />Exporte o componente como default e adicione o plugin. O build gera o vitral.json.
// vite.config.js
import vue from '@vitejs/plugin-vue'
import vitral from 'vitral/vite'
export default { plugins: [vue(), vitral()] }React, Next, Vue, Nuxt, Angular, Svelte, Solid, Preact, Lit e JS puro. Host e remote não precisam combinar.
<template>
<VitralRemote name="carrinho" :props="{ userId }">
<template #fallback>Carregando…</template>
</VitralRemote>
</template><vitral-remote name="carrinho" props='{"userId": 42}'></vitral-remote>O CSS de cada remote vale só dentro dele. Tailwind funciona. Para isolar também o CSS do host, use Shadow DOM.
/* CSS do remote */
.botao { color: red }
/* depois do build */
[data-vitral-scope="carrinho"] .botao { color: red }<Remote name="carrinho" isolate="shadow" />Cada remote mostra o próprio erro. tentarDeNovo monta só aquele remote de novo.
<Remote
name="carrinho"
fallback={<p>Carregando…</p>}
error={(erro, tentarDeNovo) => <button onClick={tentarDeNovo}>Tentar de novo</button>}
onError={(erro) => log(erro.code)}
/>O código de host mínimo tem 3,4 kB com brotli. Sem build no host, uma tag de script basta.
<script type="module" src="https://cdn.jsdelivr.net/npm/vitral/dist/auto.js"></script>
<vitral-remote src="https://cdn.empresa.com/carrinho/vitral.json"></vitral-remote>| Module Federation | single-spa | qiankun | Next.js Multi-Zones | vitral | |
|---|---|---|---|---|---|
| Configuração no host | Plugin no build | Root config e import map | registerMicroApps e start | Um app Next por zona e rewrites | configure({ remotes }) |
| Frameworks | Combinar dependências em shared | Um adaptador por framework | Qualquer, com entrada HTML | Só Next | Qualquer |
| Isolamento de CSS | Nenhum | Nenhum | Shadow DOM ou prefixo | Por página | Escopo automático ou Shadow DOM |
| Código de host (brotli) | 19,4 kB | 5,8 kB | 37,9 kB | Runtime do Next em cada zona | 3,4 kB |
| Trocar de área | Sem recarregar | Sem recarregar | Sem recarregar | Recarrega a página | Sem recarregar |
| Confere o hash do JS (SRI) | Não, por padrão | Não, por padrão | Não, por padrão | Não, por padrão | Sim, quando o manifesto tem hash |
Comparação com a configuração padrão de cada ferramenta. Plugins e configuração extra podem mudar estes valores.
Vindo de uma dessas ferramentas? Veja Migração.