Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso Single SPA: roteando micro front-ends de forma avançada

Single SPA: roteando micro front-ends de forma avançada

Identificando múltiplos MFEs - Apresentação

Olá, estudante! Tudo bem? Eu sou o Pedro Mello, instrutor na Alura, e quero te dar boas-vindas a mais um curso de React aqui na plataforma.

Audiodescrição: Pedro se descreve como um homem branco, de cabelos e barba castanho-escuros, e olhos castanho-escuros. Ele veste uma camisa preta, e está em um ambiente iluminado em azul, com instrumentos e uma estante com enfeites ao fundo.

O que vamos aprender?

Este curso será voltado para micro front-ends, onde vamos aprender conceitos mais avançados, sendo o principal deles o roteamento avançado entre micro front-ends.

Para isso, continuaremos utilizando o projeto HomeHub. O HomeHub é o projeto de uma dashboard voltada para a automação de atividades residenciais.

Na página da aplicação, temos uma navbar e uma dashboard com alguns componentes feitos anteriormente, como a seção "Usuários da família", gráficos mostrando o consumo de água, entre outras coisas implementadas. Entretanto, vamos implementar ainda mais elementos.

Nesse projeto, iremos:

Este curso tem muito conteúdo interessante e estamos empolgados para começar essa aventura, aprendendo sobre o roteamento avançado e fazendo o login funcionar nessa aplicação.

Pré-requisitos

Como o conteúdo deste curso é um pouco mais avançado, recomendamos:

Conclusão

No próximo vídeo, começaremos a abordar alguns conceitos muito importantes para seguirmos essa caminhada de desenvolvimento de micro front-ends.

Te aguardamos na sequência!

Identificando múltiplos MFEs - Adicionando identificadores

Antes de começarmos com os conceitos mais avançados do desenvolvimento de aplicações com micro front-end, vamos recapitular alguns pontos que já trabalhamos em outros cursos.

Esses pontos serão muito úteis para seguirmos com os conceitos mais avançados, principalmente na parte de roteamento, que é nosso foco.

Configurando IDs para micro front-ends

Acessando o Figma do projeto

Antes de voltarmos para o código no Visual Studio Code, vamos acessar no navegador a aba onde está o design do Figma desse projeto.

O HomeHub é um projeto de automação residencial, no qual já trabalhamos e temos algumas telas prontas, além de algumas pequenas funcionalidades implementadas.

Caso esteja começando agora, você receberá um projeto com alguns componentes e configurações feitos com o micro front-end utilizando o Single SPA, framework usado nestes cursos voltados para micro front-end.

Executando micro front-ends

Já temos uma boa implementação na primeira tela, e nosso objetivo agora será conectar com uma página de login existente. Porém, antes disso, de volta ao projeto do HomeHub no Visual Studio Code, na linha 50 do arquivo index.ejs do orquestrador, chamado de "root" no projeto, o orquestrador roda na porta 9000, a navbar na porta 8500, e a dashboard na porta 8501.

index.ejs:

// código omitido

<script type="systemjs-importmap">
  {
    "imports": {
      "@home-hub/root-config": "//localhost:9000/home-hub-root-config.js",
      "@home-hub/react-navbar": "//localhost:8500/home-hub-react-navbar.js",
      "@home-hub/react-dashboard": "//localhost:8501/home-hub-react-dashboard.js",
      "@home-hub/react-login": "//localhost:8502/home-hub-react-login.js"
    }
  }
</script>

// código omitido

Vamos rodar esses projetos, os quais, na verdade, são os micro front-ends. Para isso, acessaremos a pasta "root" no terminal com o comando cd, e depois executaremos o comando npm start, mas sem passar a porta, pois ele irá rodar o orquestrador na porta 9000 por padrão.

cd root
npm start

Com o orquestrador em execução, iremos rodar a navbar. Primeiramente, voltaremos uma pasta com o comando cd .., e na sequência vamos navegar para o react-navbar.

cd ..
cd react-navbar

Feito isso, usaremos novamente o comando npm start, mas passando a porta 8500 (--port 8500).

npm start -- --port 8500

Por fim, abriremos mais um terminal, onde vamos voltar uma pasta com cd .. da mesma form e navegar para react-dashboard. Após isso, podemos executar o comando npm start passando a porta 8501.

cd ..
cd react-dashboard
npm start -- --port 8501

Após executar, vamos retornar ao navegador para conferir como o projeto está rodando e qual é o estado zero em que iniciamos esta série de aulas.

Dois micro front-ends na mesma rota

Com o orquestrador e os dois micro front-ends em execução, acessaremos localhost:9000 no navegador, onde roda o projeto HomeHub.

Já temos alguns cards e parte da dashboard também está implementada, juntamente com a navbar interativa. A questão agora é que temos dois micro front-ends em execução na mesma rota: o micro front-end da navbar e o micro front-end da dashboard rodando simultaneamente na rota 9000.

A documentação do Single SPA diz que os micro front-ends não geram hierarquia entre eles, ou seja, são todos parentes, mas eles não têm a hierarquia de pai e filho, ou seja, não têm uma ordem pré-definida.

Qual é o problema disso e qual questão precisamos resolver de acordo com a documentação?

Quando fazemos uma alteração no código (por exemplo, uma alteração na navbar), também é feita uma alteração no DOM. Toda alteração no código gera uma alteração no DOM, principalmente, porque trabalhamos com React dentro desses micro front-ends.

O ciclo de vida do componente em tela segue a mesma lógica do Virtual DOM, um conceito que, provavelmente, está fixado na sua mente. Caso não esteja, o Virtual DOM cria uma cópia em memória do DOM com as alterações feitas e faz uma comparação.

Da mesma forma que fazemos o pull request, comparando com o conteúdo onde ele será "mergeado" e o que colocamos no pull request de fato, assim funciona no DOM: o Virtual DOM faz essa comparação com o DOM e, a partir dessa diferença, gera o conteúdo em tela com as atualizações realizadas.

O problema é que, como dois micro front-ends compartilham o mesmo DOM e não geram hierarquia de um para o outro, existe uma chance de, enquanto editamos, eles trocarem de lugar no DOM.

Dessa forma, a navbar que está no topo pode vir para baixo; a dashboard que está embaixo pode sobrepor a posição da navbar. Nesse caso, com uma dashboard acima da navbar, a navbar perde um pouco o sentido, por parecer mais um footer do que uma header.

Como a documentação é bem explícita sobre os micro front-ends não gerarem hierarquia entre si, existe uma solução, a qual nomearemos um pouco mais especificamente em breve.

Para solucionar esse problema, podemos identificar os micro front-ends a partir de uma div com um id específico. Ao fazer isso, os micro front-ends terão os DOMs trabalhando de forma separada.

Criando uma div com id='single-spa-application:react-navbar'

Segundo a documentação, existe um nome específico para o id funcionar corretamente. De volta ao VS Code, abriremos a pasta "react-navbar > src" e acessaremos o arquivo App.tsx.

Basicamente, a documentação diz para envolver a aplicação em uma div e passar um id para ela. O componente final renderizado em tela está localizado entre as linhas 131 e 165 em App.tsx.

Na linha 132, vamos abrir essa div, por enquanto vazia, e moveremos o fechamento dela para a linha 65, de modo a encerrá-la logo abaixo do componente Box.

App.tsx (react-navbar > src):

// código omitido

return (
  <div>
    <Box sx={{ flexGrow: 1 }}>
      <AppBar position='static' sx={{ backgroundColor: '#9C27B0' }}>
        <Toolbar>
          <MenuItem onClick={toggleDrawer(true)}>
            <img src={HomeHubLogo} style={{ width: '176px' }} />
          </MenuItem>
          <Box sx={{ flexGrow: 1 }} />
          <Box sx={{ display: { xs: 'none', md: 'flex' } }}>
            <MenuItem onClick={handleProfileMenuOpen}>
              <IconButton
                size='large'
                edge='end'
                aria-label='account of current user'
                aria-haspopup='true'
                onClick={() => {}}
                color='inherit'
              >
                <AccountCircle />
              </IconButton>
            </MenuItem>
            <IconButton size='large' color='inherit'>
              <Badge color='error'>
                <NotificationsIcon />
              </Badge>
            </IconButton>
          </Box>
        </Toolbar>
      </AppBar>
      <Drawer open={open} onClose={toggleDrawer(false)}>
        {DrawerList}
      </Drawer>
      {renderMenu}
    </Box>
  </div>
);

// código omitido

A documentação fala especificamente que essa div deve ter um id começando com o prefixo single-spa-application seguido de dois pontos (:) e o nome dado para a aplicação.

Código retirado da documentação do Single SPA:

<div id="single-spa-application:app-name"></div>
<div id="single-spa-application:other-app"></div>

Vamos copiar esse prefixo e voltar ao VS Code para atribuir o id igual a single-spa-application seguido de dois pontos e o nome da aplicação, que é react-navbar.

App.tsx (react-navbar > src):

// código omitido

return (
  <div id='single-spa-application:react-navbar'>
    // código omitido
  </div>
);

// código omitido

Criando uma div com id='single-spa-application:react-dashboard'

Após salvar, faremos o mesmo com a dashboard: basta copiar a linha da div e acessar o arquivo root.component.tsx da pasta "react-dashboard > src".

Na linha 9, colaremos a div copiada anteriormente, mas em vez de react-navbar ao final do id, passaremos react-dashboard.

Para finalizar, fecharemos a div na linha 30.

root.component.tsx:

// código omitido

return (
  <div id='single-spa-application:react-dashboard'>
    <Box
      width={3 / 4}
      my={4}
      display='flex'
      alignItems='center'
      gap={4}
      p={2}
      sx={{ margin: 'auto' }}
    >
      <Grid container spacing={2}>
        <Grid item xs={12}>
          <HeroCard />
        </Grid>
        <Grid item xs={4}>
          <UsersCard />
        </Grid>
        <Grid item xs={4}>
          <WaterCard />
        </Grid>
      </Grid>
    </Box>
  </div>
);

Conclusão

Segundo a documentação, com essa simples configuração, temos os micro front-ends com seus próprios DOMs em funcionamento, de forma separada. Na sequência, entenderemos qual é a utilidade disso, tratando-se de desenvolvimento de aplicações micro front-ends.

Te aguardamos no próximo vídeo para continuarmos abordando o conceito da identificação única nos micro front-ends!

Identificando múltiplos MFEs - Alterações simultâneas no DOM

Agora que configuramos um id para os dois micro front-ends, vamos entender um pouco melhor, segundo a documentação: por que precisamos configurar esse id? Qual vantagem isso nos trará em termos de desenvolvimento? Entenderemos isso na prática, partindo da documentação oficial do Single SPA.

A importância da configuração de IDs para micro front-ends

Acessando a documentação

Com a documentação aberta no navegador na página de configuração do Single SPA, encontramos a seção "Two registered applications simultaneously".

A partir dessa parte da documentação, podemos tentar entender um pouco mais sobre o porquê de utilizarmos uma div com um id separado para cada micro front-end desenvolvido.

Tradução de trecho retirado da documentação:

Duas aplicações registadas simultaneamente

Sim, é possível. E na verdade não é tão assustador se você fizer direito. E uma vez que você faz, é realmente muito poderoso. Uma abordagem para fazer isso é criar uma <div> para cada aplicativo, para que eles nunca tentem modificar o mesmo DOM ao mesmo tempo.

A <div> precisará de um id começando com o prefixo single-spa-application: e então o nome do seu aplicativo. Por exemplo, se você tivesse um aplicativo chamado app-name, você faria uma <div> com o id single-spa-application:app-name.

Um exemplo com múltiplas aplicações seria assim:

<div id="single-spa-application:app-name"></div>
<div id="single-spa-application:other-app"></div>

Ela diz que conseguimos ter dois micro front-ends em execução simultaneamente na mesma rota e que isso não é complexo.

Conforme feito anteriormente, precisamos apenas criar uma div para envolver os micro front-ends, onde passamos um id com o prefixo single-spa-application: seguido do nome da aplicação, que no nosso caso, foram react-navbar e react-dashboard.

Dessa forma, ao acessar a aplicação e rodar o console de desenvolvimento, notaremos que existe uma div criada com um id específica, da mesma forma que encontramos na documentação.

Agora que temos o aval da documentação do motivo para termos feito os processos do vídeo anterior, vamos entender como isso funciona na prática.

Analisando o projeto

De volta à aba onde é executado o projeto, vamos abrir o console de desenvolvimento. No código da página, o primeiro elemento na tag body é a div da navbar. Sendo assim, temos uma div com o id referente ao nome dessa aplicação, que é @home-hub/react-navbar.

Não adicionamos @home-hub no código anteriormente, apenas react-navbar, mas o orquestrador faz essa configuração automaticamente e coloca o nome completo da aplicação, que inclui o @home-hub.

Na sequência, temos o modal presentation, um componente que está por fora, então podemos desconsiderar esse segundo elemento. O terceiro componente, que está de fato renderizado em tela, é a div da dashboard, onde temos o id single-spa-application:@home-hub/react-dashboard.

A partir desse momento, se fizermos alterações no código, não haverá risco dos micro front-ends sobreporem a posição um do outro.

A navbar está configurada para aparecer primeiro e com o id marcado para ela, então qualquer alteração na navbar não terá interferência no DOM referente à dashboard, que também terá um nó no DOM e um id separados para ela.

Relembrando os conceitos de id no HTML, sabemos que ele tende a ser imutável, a não ser que haja um force para uma atualização. Dessa forma, se fizermos alterações somente na navbar, apenas ela irá atualizar, e vice-versa, então não há risco das posições serem trocadas.

Retornando ao código

Para exemplificar o que falamos, voltaremos ao código. Na pasta "react-dashboard > components > HeroCard", vamos acessar o arquivo index.tsx.

Na linha 19, onde temos o texto "Confira as informações da sua casa inteligente!", vamos acrescentar o trecho "Testando alterações simultâneas no DOM.", a título de teste.

index.tsx (react-dashboard > src > components > HeroCard):

// código omitido

<Box>
  <Typography variant='h5'>Olá, usuário!</Typography>
  <Typography>
    Confira as informações da sua casa inteligente! Testando alterações simultâneas no DOM.
  </Typography>
</Box>

// código omitido

Após salvar, podemos retornar ao navegador para conferir o resultado. Ao atualizar a página, a alteração que fizemos é refletida, a tela é recarregada, e as aplicações continuam no mesmo lugar.

Ou seja, a condição do DOM de imutabilidade, referente ao id que esses micro front-ends desempenham no navegador, é respeitada conforme esperado.

Conclusão

Esse é um conceito muito importante de lembrar quando buscamos a interação entre dois ou mais micro front-ends na mesma rota. O essencial é respeitar o id referente a cada um desses micro front-ends, os quais terão seus nós no DOM separados e não irão interferir nas renderizações.

Te esperamos no próximo vídeo, onde continuaremos aprendendo sobre esses conceitos avançados de desenvolvimento de aplicações micro front-ends. Até lá!

Sobre o curso Single SPA: roteando micro front-ends de forma avançada

O curso Single SPA: roteando micro front-ends de forma avançada possui 127 minutos de vídeos, em um total de 46 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas