O Angular continua a evoluir, introduzindo melhorias significativas para desenvolvedores. Desde o Angular v17, a CLI do Angular adotou um construtor baseado em ESBuild , substituindo a solução Webpack original . Além disso, o uso de módulos não é mais necessário, pois o Angular agora prioriza componentes autônomos.
No âmbito dos micro frontends (MFE), a Federação de Módulos desempenha um papel fundamental ao permitir a criação de aplicações web modulares, escaláveis e sustentáveis, compondo partes desenvolvidas de forma independente em tempo de execução. Essa abordagem foi introduzida pela primeira vez no Webpack 5, trazendo o conceito de microsserviços para o frontend.
Federação Nativa é uma técnica emergente que utiliza funcionalidades nativas do JavaScript e módulos ECMAScript (ESM) para implementar micro frontends sem ferramentas de build como o Webpack . Ela utiliza importações dinâmicas e o sistema ESM para federar módulos, simplificando o processo.
Com a migração do Angular CLI do Webpack para o ESBuild, surgem novos desafios na adoção da arquitetura MFE. É aqui que a Federação Nativa se torna particularmente relevante, especialmente para projetos que utilizam Angular v17 ou versões mais recentes.
Neste tutorial, criaremos um MFE simples usando Angular e Native Federation, utilizando o @angular-architects/native-federation
pacote para agilizar o processo de desenvolvimento.
- Criando o espaço de trabalho Angular
- Criando os aplicativos/projetos Angular
- Adicionando Material Angular
- Adicionando a Native Federation ao projeto
- Configurando o aplicativo Shell (host)
- Configurando o aplicativo MFE1 (remoto)
- Adicionando rotas ao aplicativo Shell
- Executando o Shell e o MFE1 (Produtos)
- Resumo
Criando o espaço de trabalho Angular
Comece criando um novo espaço de trabalho Angular para hospedar seus diferentes MFEs. Certifique-se de ter a CLI Angular instalada localmente e execute:
ng new angular-mfe-native-federation --create-application=false
Isso gera um espaço de trabalho limpo para desenvolver vários projetos usando a arquitetura MFE.
A imagem a seguir é a saída do comando anterior:
Criando os aplicativos/projetos Angular
Em seguida, gere os aplicativos. Criaremos um Shell
aplicativo e um Products
aplicativo (nosso primeiro MFE). Para simplificar, vamos nos limitar a esses dois por enquanto.
Para gerar o aplicativo Shell, execute:
ng generate application shell --prefix app-shell
Você deverá ver um projeto recém-criado:
Agora, repita o comando para o Products
aplicativo:
ng generate application products --prefix app-products
Agora você tem dois aplicativos em seu espaço de trabalho.
Adicionando Material Angular
Para ajudar a estilizar os aplicativos, usaremos o Angular Material . Use o seguinte esquema:
ng add @angular/material
Você pode encontrar erros, então certifique-se de que o Angular Material também seja adicionado a cada projeto individualmente:
ng add @angular/material --project shell
ng add @angular/material --project products
Corrigindo os estilos para cada projeto
Se os estilos não forem exibidos corretamente após adicionar o Material Angular, abra o angular.json
arquivo e verifique se styles.scss
o tema do Material selecionado está listado:
"styles": [
"@angular/material/prebuilt-themes/azure-blue.css",
"projects/shell/src/styles.scss"
],
Com essa alteração, o CSS deve ser exibido corretamente ao executar e construir os projetos.
Adicionando a Native Federation ao projeto
Para habilitar o conceito MFE, adicione a Native Federation instalando:
npm i -D @angular-architects/native-federation
Este pacote será instalado como uma dependência de desenvolvimento e também adicionará as dependências de produção necessárias ao package.json
arquivo.
Configurando o aplicativo Shell (host)
Em seguida, configure o Shell como o host capaz de carregar os controles remotos (MFEs):
ng g @angular-architects/native-federation:init --project shell --port 4200 --type dynamic-host
O aplicativo Shell será executado na porta 4200.
Vamos nos concentrar no desenvolvimento deste projeto antes de passar para o próximo.
Criando um componente de cabeçalho
Gere um componente de cabeçalho para navegação entre MFEs usando Angular CLI:
ng g c header --project shell
Observe que, por padrão, todos os componentes são autônomos e não estamos mais usando NgModules
.
Atualize header.component.html
com:
<mat-toolbar>
<button mat-icon-button [routerLink]="['/']">
<mat-icon>home</mat-icon>
</button>
<button mat-button [routerLink]="['/products']">
Products
</button>
</mat-toolbar>
É uma barra de ferramentas de materiais simples com um ícone de página inicial que nos permite voltar à página inicial e um botão que permite ao usuário navegar até o aplicativo Produtos.
O header.component.ts
arquivo ficará parecido com o seguinte:
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-shell-header',
imports: [RouterLink, MatIconModule, MatToolbarModule, MatButtonModule],
templateUrl: './header.component.html'
})
export class HeaderComponent { }
Estamos importando os módulos Material necessários. Como este componente está sendo usado apenas para roteamento, não precisamos adicionar nenhuma lógica, pois o Angular cuidará disso para nós. E como não precisamos de nenhum CSS personalizado para este exemplo, também podemos excluir o header.component.scss
arquivo, juntamente com sua entrada no arquivo HeaderComponent
.
Criando um componente Home
Em seguida, gere uma página inicial básica que pode ser exibida por padrão quando carregamos nosso aplicativo Angular:
ng g c header --project shell
Este componente exibirá um Cartão de Material com a palavra “Casa”. Aqui está o conteúdo do home.component.ts
arquivo:
import { Component } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
@Component({
selector: 'app-shell-home',
imports: [MatCardModule],
template: `
<mat-card appearance="outlined">
<mat-card-content>Home</mat-card-content>
</mat-card>
`
})
export class HomeComponent { }
Vamos manter tudo simples neste exemplo e, claro, você pode adicionar um design bacana para sua página inicial.
Agora podemos passar para a aplicação dos produtos.
Configurando o aplicativo MFE1 (remoto)
Transforme o products
projeto em um MFE:
ng g @angular-architects/native-federation:init --project products --port 4201 --type remote
Este projeto será executado na porta 4201. Ajuste a porta projects/shell/public/federation.manifest.json
também:
{
"products": "http://localhost:4201/remoteEntry.json"
}
Ao adicionar outros controles remotos ao seu projeto, você também precisará alterar este arquivo adequadamente.
Em seguida, modificaremos o AppComponent
interior do products
projeto:
import { Component } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
@Component({
selector: 'app-products-root',
imports: [MatCardModule],
template: `
<mat-card appearance="outlined">
<mat-card-content>Products App</mat-card-content>
</mat-card>
`
})
export class AppComponent { }
Mais uma vez, estamos mantendo tudo simples, e você poderá adicionar qualquer design necessário a este projeto para que seu MFE funcione corretamente.
Adicionando rotas ao aplicativo Shell
Agora é hora de juntar tudo! Vamos voltar ao app.routes.ts
arquivo do projeto shell e adicionar as rotas:
import { loadRemoteModule } from '@angular-architects/native-federation';
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
export const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{
path: 'products',
loadComponent: () =>
loadRemoteModule('products', './Component').then((m) => m.AppComponent),
},
{
path: '**',
component: HomeComponent,
}
];
O Angular não possui uma API que nos permita carregar módulos remotos. É aí que @angular-architects/native-federation
entra o pacote que instalamos anteriormente.
Este pacote nos permite carregar preguiçosamente um componente remove usando o loadRemoteModule
recurso. Podemos usá-lo para carregar preguiçosamente um componente independente usando a loadComponent
função da API Angular.
Executando o Shell e o MFE1 (Produtos)
Por fim, vamos executar nosso aplicativo localmente para ver o MFE em ação:
ng serve shell
ng serve products
Precisamos abrir dois terminais e executar cada ng serve
comando. Depois, podemos abrir nosso aplicativo usando :http://localhost:4200
E se navegarmos até a /products
rota, devemos ver nossos produtos MFE:
Resumo
Nesta publicação, abordamos o processo de configuração de um espaço de trabalho Angular com micro frontends usando a Federação de Módulos. Criamos uma aplicação shell e uma aplicação remota de produtos, integramos o Angular Material para estilização e configuramos a Federação Nativa para arquitetura modular. Por fim, configuramos o roteamento e testamos ambas as aplicações em execução local. Essa configuração básica permite aplicações web escaláveis e modulares usando os recursos de MFE do Angular.
Referências e para saber mais:
- https://www.angulararchitects.io/pt/blog/micro-frontends-com-angular-moderno-parte-1-standalone-e-esbuild/
- https :// www . npmjs . com / pacote / @ angular – arquitetos / nativo – federação
Veja o código-fonte completo no GitHub .