Criação de um portal para microfrontends usando o AWS Amplify, Angular e Module Federation - Recomendações da AWS

Criação de um portal para microfrontends usando o AWS Amplify, Angular e Module Federation

Milena Godau e Pedro Garcia, Amazon Web Services

Resumo

Uma arquitetura de microfrontend permite que várias equipes trabalhem em diferentes partes de uma aplicação de frontend de forma independente. Cada equipe pode desenvolver, criar e implantar um fragmento do frontend sem interferir em outras partes da aplicação. Do ponto de vista do usuário final, parece ser uma aplicação única e coesa. No entanto, eles estão interagindo com várias aplicações independentes publicadas por equipes diferentes.

Este documento descreve como criar uma arquitetura de microfrontend usando o AWS Amplify, a estrutura de frontend Angular e o Module Federation. Neste padrão, os microfrontends são combinados no lado do cliente por uma aplicação shell (ou principal). A aplicação shell atua como um contêiner que recupera, exibe e integra os microfrontends. A aplicação shell manipula o roteamento global, que carrega diferentes microfrontends. O plug-in @angular-architects/module-federation integra o Module Federation com o Angular. Você implanta a aplicação shell e os microfrontends usando o AWS Amplify. Os usuários finais acessam a aplicação por meio de um portal baseado na web.

O portal está dividido verticalmente. Isso significa que os microfrontends são visualizações inteiras ou grupos de visualizações, em vez de partes da mesma visualização. Portanto, a aplicação shell carrega apenas um microfrontend por vez.

Os microfrontends são implementados como módulos remotos. A aplicação shell carrega lentamente esses módulos remotos, o que adia a inicialização do microfrontend até que ela seja necessária. Essa abordagem otimiza a performance da aplicação carregando somente os módulos necessários. Isso reduz o tempo de carregamento inicial e melhora a experiência geral do usuário. Além disso, você compartilha dependências comuns entre os módulos por meio do arquivo de configuração do webpack (webpack.config.js). Essa prática promove a reutilização de código, reduz a duplicação e simplifica o processo de empacotamento.

Pré-requisitos e limitações

Pré-requisitos

Versões do produto

  • CLI do Angular versão 13.1.2 ou posterior

  • @angular-architects/module-federation versão 14.0.1 ou posterior

  • webpack versão 5.4.0 ou posterior

  • AWS Amplify Gen 1

Limitações

Uma arquitetura de microfrontend é uma abordagem poderosa para criar aplicações web escaláveis e resilientes. No entanto, é fundamental entender os seguintes desafios em potencial antes de adotar essa abordagem:

  • Integração: um dos principais desafios é o aumento potencial da complexidade em comparação com frontends monolíticos. Orquestrar vários microfrontends, lidar com a comunicação entre eles e gerenciar dependências compartilhadas pode ser mais complexo. Além disso, pode haver uma sobrecarga na performance associada à comunicação entre os microfrontends. Essa comunicação pode aumentar a latência e reduzir a performance. Isso precisa ser resolvido por meio de mecanismos eficientes de mensagens e estratégias de compartilhamento de dados.

  • Duplicação de código: como cada microfrontend é desenvolvido de forma independente, existe o risco de duplicar o código para funcionalidades comuns ou bibliotecas compartilhadas. Isso pode aumentar o tamanho geral da aplicação e introduzir desafios de manutenção.

  • Coordenação e gerenciamento: coordenar os processos de desenvolvimento e implantação em vários microfrontends pode ser um desafio. Garantir o versionamento consistente, o gerenciamento de dependências e a manutenção da compatibilidade entre os componentes se torna mais importante em uma arquitetura distribuída. Estabelecer uma governança clara, diretrizes e pipelines automatizados de teste e implantação é essencial para uma colaboração e entrega perfeitas.

  • Teste: testar arquiteturas de microfrontend pode ser mais complexo do que testar frontends monolíticos. Isso requer esforço adicional e estratégias de teste especializadas para realizar testes de integração entre componentes e testes de ponta a ponta, além de validar experiências de usuário consistentes em vários microfrontends.

Antes de se comprometer com a abordagem de microfrontend, recomendamos que você consulte Understanding and implementing micro-frontends on AWS.

Arquitetura

Em uma arquitetura de microfrontend, cada equipe desenvolve e implanta recursos de forma independente. A imagem a seguir mostra como várias equipes de DevOps trabalham juntas. A equipe do portal desenvolve a aplicação shell. A aplicação shell atua como um contêiner. Ela recupera, exibe e integra as aplicações de microfrontend publicadas por outras equipes de DevOps. Você usa o AWS Amplify para publicar a aplicação shell e as aplicações de microfrontend.

Publicar vários microfrontends em uma aplicação shell que o usuário acessa por meio de um portal da web.

O diagrama da arquitetura mostra o seguinte fluxo de trabalho:

  1. A equipe do portal desenvolve e mantém a aplicação shell. A aplicação shell orquestra a integração e a renderização dos microfrontends para compor o portal geral.

  2. As equipes A e B desenvolvem e mantêm um ou mais microfrontends ou recursos integrados ao portal. Cada equipe pode trabalhar de forma independente em seus respectivos microfrontends.

  3. O usuário final faz a autenticação usando o Amazon Cognito.

  4. O usuário final acessa o portal e a aplicação shell é carregada. Conforme o usuário navega, a aplicação shell lida com o roteamento e recupera o microfrontend solicitado, carregando seu pacote.

Ferramentas

Serviços da AWS

  • O AWS Amplify é um conjunto de ferramentas e recursos desenvolvidos especificamente para permitir aos desenvolvedores de frontend para a web e de dispositivos móveis criarem aplicações full-stack de forma rápida e fácil na AWS. Neste padrão, você usa a CLI do Amplify para implantar as aplicações de microfrontend do Amplify.

  • A AWS Command Line Interface (AWS CLI) é uma ferramenta de código aberto que auxilia na interação com Serviços da AWS por meio de comandos no seu shell de linha de comandos.

Outras ferramentas

  • @angular-architects/module-federation é um plugin que integra o Angular com o Module Federation.

  • O Angular é uma estrutura de aplicações web de código aberto para criar aplicações de página única modernas, escaláveis e testáveis. Ele segue uma arquitetura modular e baseada em componentes que promove a reutilização e a manutenção do código.

  • O Node.js é um ambiente de runtime de JavaScript orientado por eventos projetado para criar aplicações de rede escaláveis.

  • O npm é um registro de software executado em um ambiente Node.js e usado para compartilhar ou emprestar pacotes e gerenciar a implantação de pacotes privados.

  • O Webpack Module Federation ajuda você a carregar código compilado e implantado de forma independente, como microfrontends ou plug-ins, em uma aplicação.

Repositório de código

O código para este padrão está disponível no repositório Micro-frontend portal using Angular and Module Federation do GitHub. Esse repositório contém as duas pastas abaixo:

  • shell-app contém o código para a aplicação shell.

  • feature1-app contém um exemplo de microfrontend. A aplicação shell busca esse microfrontend e o exibe como uma página dentro da aplicação do portal.

Práticas recomendadas

As arquiteturas de microfrontend oferecem inúmeras vantagens, mas também introduzem complexidade. A seguir estão algumas das práticas recomendadas para um desenvolvimento tranquilo, código de alta qualidade e uma ótima experiência do usuário:

  • Planejamento e comunicação: para agilizar a colaboração, invista em planejamento antecipado, design e canais de comunicação claros.

  • Consistência do design: aplique um estilo visual consistente em microfrontends usando sistemas de design, guias de estilo e bibliotecas de componentes. Isso proporciona uma experiência de usuário coesa e acelera o desenvolvimento.

  • Gerenciamento de dependências: como os microfrontends evoluem de forma independente, adote contratos padronizados e estratégias de versionamento para gerenciar dependências de forma eficaz e evitar problemas de compatibilidade.

  • Arquitetura de microfrontend: para permitir o desenvolvimento e a implantação independentes, cada microfrontend deve ter uma responsabilidade clara e bem definida por uma funcionalidade encapsulada.

  • Integração e comunicação: para facilitar a integração e minimizar conflitos, defina contratos e protocolos de comunicação claros entre microfrontends, incluindo APIs, eventos e modelos de dados compartilhados.

  • Teste e garantia de qualidade: implemente pipelines de automação de testes e integração contínua para microfrontends. Isso melhora a qualidade geral, reduz o esforço de testes manuais e valida a funcionalidade entre as interações de microfrontend.

  • Otimização de performance: monitore continuamente as métricas de performance e acompanhe as dependências entre microfrontends. Isso ajuda você a identificar gargalos e manter a performance ideal da aplicação. Use ferramentas de monitoramento de performance e análise de dependências para essa finalidade.

  • Experiência do desenvolvedor: concentre-se na experiência do desenvolvedor fornecendo documentação, ferramentas e exemplos claros. Isso ajuda você a otimizar o desenvolvimento e integrar novos membros da equipe.

Épicos

TarefaDescriçãoHabilidades necessárias

Crie a aplicação shell.

  1. Na CLI do Angular, insira o seguinte comando:

    ng new shell --routing
  2. Insira o seguinte comando para acessar a pasta do projeto:

    cd shell
    nota

    A estrutura de pastas e projetos para as aplicações shell e de microfrontend pode ser totalmente independente. Elas podem ser tratadas como aplicaçãos independentes do Angular.

Desenvolvedor de aplicativos

Instale o plug-in .

Na CLI do Angular, digite o seguinte comando para instalar o plug-in @angular-architects/module-federation:

ng add @angular-architects/module-federation --project shell --port 4200
Desenvolvedor de aplicativos

Adicione o URL do microfrontend como uma variável de ambiente.

  1. Abra o arquivo environment.ts.

  2. Adicione mfe1URL: 'http://localhost:5000' ao objeto environment:

    export const environment = { production: false, mfe1URL: 'http://localhost:5000', };
  3. Salve e feche o arquivo environment.ts.

Desenvolvedor de aplicativos

Defina o roteamento.

  1. Abra o arquivo app-routing.module.ts.

  2. Na CLI do Angular, digite o seguinte comando para importar o módulo loadRemoteModule do plug-in @angular-architects/module-federation:

    import { loadRemoteModule } from '@angular-architects/module-federation';
  3. Defina a rota padrão da seguinte forma:

    { path: '', pathMatch: 'full', redirectTo: 'mfe1' },
  4. Defina a rota para o microfrontend:

    { path: 'mfe1', loadChildren: () => loadRemoteModule({ type: 'module', remoteEntry: `${environment.mfe1URL}/remoteEntry.js`, exposedModule: './Module' }) .then(m => m.Mfe1Module) },
  5. Salve e feche o arquivo app-routing.module.ts.

Desenvolvedor de aplicativos

Declare o módulo mfe1.

  1. Na pasta src, crie um novo arquivo chamado decl.d.ts.

  2. Abra o arquivo decl.d.ts.

  3. Adicione o seguinte ao arquivo:

    declare module 'mfe1/Module';
  4. Salve e feche o arquivo decl.d.ts.

Desenvolvedor de aplicativos

Prepare o pré-carregamento para o microfrontend.

O pré-carregamento do microfrontend ajuda o webpack a negociar adequadamente as bibliotecas e pacotes compartilhados.

  1. Abra o arquivo main.ts.

  2. Substitua o conteúdo pelo seguinte:

    import { loadRemoteEntry } from '@angular-architects/module-federation'; Promise.all([ loadRemoteEntry(`${environment.mfe1URL}/remoteEntry.js`, 'mfe1'), ]) .catch(err => console.error('Error loading remote entries', err)) .then(() => import('./bootstrap')) .catch(err => console.error(err));
  3. Salve e feche o arquivo main.ts.

Desenvolvedor de aplicativos

Ajuste o conteúdo HTML.

  1. Abra o arquivo app.component.html.

  2. Substitua o conteúdo pelo seguinte:

    <h1>Shell application is running!</h1> <router-outlet></router-outlet>
  3. Salve e feche o arquivo app.component.html.

Desenvolvedor de aplicativos
TarefaDescriçãoHabilidades necessárias

Crie o microfrontend.

  1. Na CLI do Angular, insira o seguinte comando:

    ng new mfe1 --routing
  2. Insira o seguinte comando para acessar a pasta do projeto:

    cd mfe1
Desenvolvedor de aplicativos

Instale o plug-in .

Insira o seguinte comando para instalar o plug-in @angular-architects/module-federation:

ng add @angular-architects/module-federation --project mfe1 --port 5000
Desenvolvedor de aplicativos

Crie um módulo e componente.

Insira os seguintes comandos para criar um módulo e um componente e exportá-los como módulo de entrada remota:

ng g module mfe1 --routing ng g c mfe1
Desenvolvedor de aplicativos

Defina o caminho de roteamento padrão.

  1. Abra o arquivo mfe-routing.module.ts.

  2. Defina a rota padrão da seguinte forma:

    { path: '', component: Mfe1Component },
  3. Salve e feche o arquivo mfe-routing.module.ts.

Desenvolvedor de aplicativos

Adicione a rota mfe1.

  1. Abra o arquivo app-routing.module.ts.

  2. Defina a rota padrão da seguinte forma:

    { path: '', pathMatch: 'full', redirectTo: 'mfe1' },
  3. Adicione a seguinte rota mfe1:

    { path: 'mfe1', loadChildren: () => import('./mfe1/mfe1.module').then((m) => m.Mfe1Module), },
  4. Salve e feche o arquivo app-routing.module.ts.

Desenvolvedor de aplicativos

Edite o arquivo webpack.config.js.

  1. Abra o arquivo webpack.config.js.

  2. Edite a seção For remotes para que corresponda ao seguinte:

    // For remotes (please adjust) name: "mfe1", filename: "remoteEntry.js", exposes: { './Module': './src/app/mfe1/mfe1.module.ts', },
  3. Na seção shared, adicione todas as dependências que a aplicação mfe1 compartilha com a aplicação shell:

    shared: share({ "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, ...sharedMappings.getDescriptors() })
  4. Salve e feche o arquivo webpack.config.js.

Desenvolvedor de aplicativos

Ajuste o conteúdo HTML.

  1. Abra o arquivo app.component.html.

  2. Substitua o conteúdo pelo seguinte:

    <router-outlet></router-outlet>
  3. Salve e feche o arquivo app.component.html.

Desenvolvedor de aplicativos
TarefaDescriçãoHabilidades necessárias

Execute a aplicação mfe1.

  1. Insira o seguinte comando para iniciar a aplicação mfe1:

    npm start
  2. Em um navegador da web, acesse http://localhost:5000.

  3. Verifique se o microfrontend pode ser executado de forma independente. A aplicação mfe1 deve ser renderizada corretamente sem erros.

Desenvolvedor de aplicativos

Execute a aplicação shell.

  1. Insira o seguinte comando para iniciar a aplicação shell:

    npm start
  2. Em um navegador da web, acesse http://localhost:4200/mfe1.

  3. Verifique se o microfrontend mfe1 está incorporado na aplicação shell. A aplicação do portal deve ser renderizada adequadamente, sem erros, e a aplicação mfe1 deve estar incorporada a ela.

Desenvolvedor de aplicativos
TarefaDescriçãoHabilidades necessárias

Crie um módulo e componente.

Na pasta-raiz da aplicação shell, insira os seguintes comandos para criar um módulo e um componente para uma página de erro:

ng g module error-page --routing ng g c error-page
Desenvolvedor de aplicativos

Ajuste o conteúdo HTML.

  1. Abra o arquivo error-page.component.html.

  2. Substitua o conteúdo pelo seguinte:

    <p>Sorry, this page is not available.</p>
  3. Salve e feche o arquivo error-page.component.html.

Desenvolvedor de aplicativos

Defina o caminho de roteamento padrão.

  1. Abra o arquivo error-page-routing.module.ts.

  2. Defina a rota padrão da seguinte forma:

    { path: '', component: ErrorPageComponent },
  3. Salve e feche o arquivo error-page-routing.module.ts.

Desenvolvedor de aplicativos

Crie uma função para carregar microfrontends.

  1. Abra o arquivo app-routing.module.ts.

  2. Crie a seguinte função:

    function loadMFE(url: string) { return loadRemoteModule({ type: 'module', remoteEntry: `${url}/remoteEntry.js`, exposedModule: './Module' }) .then(m => m.Mfe1Module) .catch( () => import('./error-page/error-page.module').then(m => m.ErrorPageModule) ); }
  3. Modifique a rota mfe1 da seguinte maneira:

    { path: 'mfe1', loadChildren: () => loadMFE(environment.mfe1URL) },
  4. Salve e feche o arquivo app-routing.module.ts.

Desenvolvedor de aplicativos

Teste o tratamento de erros.

  1. Se ainda não estiver em execução, digite o seguinte comando para iniciar a aplicação shell:

    npm start
  2. Em um navegador da web, acesse http://localhost:4200/mfe1.

  3. Verifique se a página de erros foi renderizada. Você deverá ver o seguinte texto:

    Sorry, this page is not available.
Desenvolvedor de aplicativos
TarefaDescriçãoHabilidades necessárias

Implante o microfrontend.

  1. Na CLI do Amplify, navegue até a pasta-raiz da aplicação de microfrontend.

  2. Insira o seguinte comando para inicializar o Amplify:

    amplify init
  3. Quando nome para seu projeto do Amplify for solicitado, pressione Enter. Isso reutiliza o nome do arquivo package.json.

  4. Quando a inicialização do projeto com a configuração acima for solicitada, insira Yes.

  5. Quando um método de autenticação for solicitado, escolha AWS Profile.

  6. Selecione o perfil que você deseja usar.

  7. Aguarde até que o Amplify inicialize o projeto. Quando esse processo for concluído, você receberá uma mensagem de confirmação no terminal.

  8. Insira o seguinte comando para adicionar uma categoria de hospedagem do Amplify ao microfrontend:

    amplify add hosting
  9. Quando o módulo do plug-in for solicitado, escolha Hosting with Amplify Console.

  10. Quando um tipo for solicitado, escolha Manual deployment.

  11. Instale as dependências npm do projeto inserindo o seguinte comando:

    npm install
  12. Publique a aplicação no console do Amplify inserindo o seguinte comando:

    amplify publish -y

    Quando a publicação estiver concluída, o Amplify retornará o URL do microfrontend.

  13. Copie o URL. Você precisa desse valor para atualizar a aplicação shell.

Desenvolvedor de aplicativos, AWS DevOps

Implante a aplicação shell.

  1. Na pasta src/app/environments, abra o arquivo environments.prod.ts.

  2. Substitua o valor mfe1URL pelo URL do microfrontend implantado:

    export const environment = { production: true, mfe1URL: 'https://<env>.<Amplify-app-ID>.amplifyapp.com' };
  3. Salve e feche o arquivo environments.prod.ts.

  4. Na CLI do Amplify, navegue até a pasta-raiz da aplicação shell.

  5. Insira o seguinte comando para inicializar o Amplify:

    amplify init
  6. Quando nome para seu projeto do Amplify for solicitado, pressione Enter. Isso reutiliza o nome do arquivo package.json.

  7. Quando a inicialização do projeto com a configuração acima for solicitada, insira Yes.

  8. Quando um método de autenticação for solicitado, escolha AWS Profile.

  9. Selecione o perfil que você deseja usar.

  10. Aguarde até que o Amplify inicialize o projeto. Quando esse processo for concluído, você receberá uma mensagem de confirmação no terminal.

  11. Adicione uma categoria de hospedagem do Amplify à aplicação shell:

    amplify add hosting
  12. Quando o módulo do plug-in for solicitado, escolha Hosting with Amplify Console.

  13. Quando um tipo for solicitado, escolha Manual deployment.

  14. Instale as dependências npm do projeto inserindo o seguinte comando:

    npm install
  15. Publique a aplicação shell no console do Amplify inserindo o seguinte comando:

    amplify publish -y

    Quando a publicação estiver concluída, o Amplify retornará o URL da aplicação shell implantada.

  16. Anote o URL da aplicação shell.

Desenvolvedor do aplicativo, proprietário do aplicativo

Ativar CORS.

Como as aplicações shell e de microfrontend são hospedadas de forma independente em domínios diferentes, você deve habilitar o compartilhamento de recursos de origem cruzada (CORS) no microfrontend. Isso permite que a aplicação shell carregue o conteúdo de uma origem diferente. Para habilitar o CORS, adicione cabeçalhos personalizados.

  1. Na CLI do Amplify, navegue até a pasta-raiz do microfrontend.

  2. Digite o comando:

    amplify configure hosting
  3. Quando uma configuração personalizada for solicitada, insira Y.

  4. Faça login no Console de gerenciamento da AWS e, em seguida, abra o console do Amplify.

  5. Escolha o microfrontend.

  6. No painel de navegação, escolha Hospedagem e, em seguida, escolha Cabeçalhos personalizados.

  7. Escolha Editar.

  8. Na janela Editar cabeçalhos personalizados, insira o seguinte:

    customHeaders: - pattern: '*.js' headers: - key: Access-Control-Allow-Origin value: '*' - key: Access-Control-Allow-Methods value: 'GET, OPTIONS' - key: Access-Control-Allow-Headers value: '*'
  9. Escolha Salvar.

  10. Reimplante o microfrontend para aplicar os novos cabeçalhos personalizados.

Desenvolvedor de aplicativos, AWS DevOps

Crie uma regra de regravação na aplicação shell.

A aplicação shell do Angular está configurada para usar o roteamento HTML5. Se o usuário fizer uma atualização definitiva, o Amplify tentará carregar uma página do URL atual. Isso gera um erro 403. Para evitar isso, adicione uma regra de regravação no console do Amplify.

Para criar a regra de regravação, siga estas etapas:

  1. Na CLI do Amplify, navegue até a pasta-raiz da aplicação shell.

  2. Digite o comando:

    amplify configure hosting
  3. Quando uma configuração personalizada for solicitada, insira Y.

  4. Abra o console do Amplify.

  5. Escolha a aplicação shell.

  6. No painel de navegação, escolha Hospedagem e, em seguida, escolha Regravações e redirecionamentos.

  7. Na página Regravações e redirecionamentos, escolha Gerenciar redirecionamentos.

  8. Escolha Abrir editor de texto.

  9. No editor JSON, insira o seguinte redirecionamento:

    [ { "source": "/<*>", "target": "/index.html", "status": "404-200", "condition": null } ]
  10. Escolha Salvar.

Desenvolvedor de aplicativos, AWS DevOps

Teste o portal da web.

  1. Em um navegador da web, digite o URL da aplicação shell implantada.

  2. Verifique se a aplicação shell e o microfrontend foram carregados corretamente.

Desenvolvedor de aplicativos
TarefaDescriçãoHabilidades necessárias

Exclua as aplicações.

Se você não precisar mais das aplicações shell e de microfrontend, exclua-as. Isso ajuda a evitar cobranças por recursos que você não está usando.

  1. Faça login no Console de gerenciamento da AWS e, em seguida, abra o console do Amplify.

  2. Escolha o microfrontend.

  3. No painel de navegação, escolha Configurações da aplicação, e, em seguida, escolha Configurações gerais.

  4. Escolha Excluir aplicação.

  5. Na caixa de confirmação, insira delete e, em seguida, escolha Excluir aplicação.

  6. Repita essas etapas para excluir a aplicação shell.

AWS geral

Solução de problemas

ProblemaSolução

Nenhum perfil da AWS disponível ao executar o comando amplify init

Se você não tiver um perfil AWS configurado, ainda poderá continuar com o comando amplify init. No entanto, você precisa selecionar a opção AWS access keys quando for solicitado o método de autenticação. Tenha sua chave de acesso e chave secreta da AWS à disposição.

Como alternativa, você pode configurar um perfil nomeado para a AWS CLI. Para obter instruções, consulte Configurações do arquivo de configuração e credenciais na documentação da AWS CLI.

Erro ao carregar entradas remotas

Se você encontrar um erro ao carregar as entradas remotas no arquivo main.ts da aplicação shell, verifique se a variável environment.mfe1URL está definida corretamente. O valor dessa variável deve ser o URL do microfrontend.

Erro 404 ao acessar o microfrontend

Se você receber um erro 404 ao tentar acessar o microfrontend local, como em http://localhost:4200/mfe1, verifique o seguinte:

  • Para a aplicação shell, verifique se a configuração de roteamento no arquivo app-routing.module.ts está configurada corretamente e se a função loadRemoteModule está chamando corretamente o microfrontend.

  • Para o microfrontend, verifique se o arquivo webpack.config.js tem a configuração exposes correta e se o arquivo remoteEntry.js está sendo gerado corretamente.

Mais informações

AWS Documentação do

Outras referências