You are on page 1of 32

 

Solução para abstração do processo de integração de fragmentos


dependency-free na arquitetura de micro frontends
Antonio A. C. G. Neto​1 
1​
Centro de Informática – Universidade Federal de Pernambuco (UFPE) 
Av. Jornalista Aníbal Fernandes, s/n - Cidade Universitária - Recife - PE 
aacgn@cin.ufpe.br
Abstract.  The  micro  frontends  architecture  has  the  potential  to  bring  about 
profound  changes  in  the  frontend  software  development  processes.  The 
single-spa  library  is  currently  one  of  the  main  tools  for  building  “web” 
applications  that  wish to use this type of architecture. In this work, an analysis 
is  performed  on  a  popular  library,  identifying difficulties in supporting legacy 
technologies and too many configuration processes. Therefore, the objective of 
this  work  is  to  develop  a solution to abstract the fragment integration process, 
in  order  to  expand  support  for  frontend  technologies  and  facilitate  the 
configuration  process.  At  the  end,  it  was  presented  the  conception  of  the  new 
tool  based  on  the  concept  of  composition  in  real  time  via  an  iframe  and 
examples  of  practical  use.  The  solution  achieved  all  the  expected  objectives; 
however,  I  can  make  reservations  about  the  difficulty  of  indexing  search 
engines  (SEO)  and  security  vulnerability windows, caused by the choice of the 
composition  tool.  Thus,  it  is  possible  to  determine  as  a  scenario  of  ideal  use 
the  market  segment  of  migration  of  legacy systems, having little attractiveness 
for real development environments that uses a digital "marketing" strategy due 
to the previous caveats. 
Keywords​:  Software  engineering.  Software  architecture.  Micro  frontends. 
Iframes. 
Resumo.  A  arquitetura  de  micro  frontends tem mostrado o potencial de trazer 
mudanças  profundas  nos  processos  de  desenvolvimento  de  “software” 
frontend.  A  biblioteca  single-spa  é,  atualmente,  uma  das  principais 
ferramentas  para  construção  de  aplicações  “web”  que  desejem  utilizar  este 
tipo  de  arquitetura.  Neste  trabalho,  é  realizada  uma  análise  sobre  a  popular 
biblioteca,  identificando  dificuldade  de  suporte  às  tecnologias  legadas  e 
demasiados  processos  de configuração. Sendo assim, torna-se o objetivo deste 
trabalho  o  desenvolvimento  de  uma  solução  para  abstrair  o  processo  de 
integração  dos  fragmentos,  de  modo  a  ampliar  o  suporte  às  tecnologias 
frontend  e  facilitar  o  processo  de  configuração.  Ao  final,  foi  apresentada  a 
concepção  da  nova  ferramenta  baseada  no  conceito  de composição em tempo 
real via iframe que e exemplos de utilização prático. A solução alcançou todos 
os  objetivos  esperados;  entretanto,  trouxe  consigo  ressalvas  quanto  à 
dificuldade  de  indexação  a  sites  de  busca  (SEO)  e  janelas  de  vulnerabilidade 
de  segurança,  causadas  pela  escolha  da  ferramenta  de  composição.  Assim, 
consegue-se  determinar  como  cenário  de  utilização  ideal  o  segmento  de 
mercado  de  migração  de  sistemas  de  legados,  possuindo  pouca  atratividade 
para  ambientes  de  desenvolvimento  real  que  se  utilize  de  estratégias  de 
“marketing” digital devido aos pontos de ressalva anteriormente descritos. 
Palavras-chave​:  ​Engenharia  de  software.  Arquitetura  de  software.  Micro 
frontends. Iframes. 

1. Introdução 
No  passado,  um  grande  número  de  aplicações  web  adotava  a  arquitetura  monolítica 
devido  à  baixa  complexidade  de  requisitos  da  época  [1].  Essa  arquitetura  orientava  o 
tratamento  de  módulos  funcionais  e  a  transmissão  de  dados  como  um  todo,  sendo 
uniformemente  configurados,  desenvolvidos  e  implementados  [2].  Porém,  a  partir  do 
 

surgimento  de  requisitos  mais  complexos,  foi  originada  uma demanda por sistemas que 


necessitavam  de  um  alto  desempenho,  de  armazenamento  e  distribuição de uma grande 
quantidade  dados  e  que  fossem  capazes  de  prover  confiabilidade,  disponibilidade  e 
escalabilidade da aplicação.​ ​
Uma  das  grandes  desvantagens  das  aplicações  monolíticas,  a  partir  de  seu 
crescimento,  era  o  tempo  de  familiarização  com  a  grande  quantidade  de  código  base, 
levando  tempo  para  novos  desenvolvedores  começarem  a  ganhar  velocidade  de 
produção  uma  vez  que  acabavam  se  sentindo  perdidos  e  não  conseguiam  identificar 
facilmente  o local correto para aplicar alterações [3]. Enquanto esse modelo apresentava 
dificuldades  conceitos  como  a  separação  por  funcionalidades,  novas  tecnologias  e 
arquiteturas  ganhavam  popularidade.  O  código  base  das  aplicações  passou  a  ser 
segmentado  em  diferentes  grupos:  Frontend,  responsável  pelo  fornecimento  de  uma 
interface  de  interação  entre  o  usuário  e  o  sistema,  e  Backend,  que  em  muitos  casos  era 
responsável  pelo  processamento  de  dados  [4].  Entre  as  diversas  técnicas  de 
desenvolvimento  Backend,  a  arquitetura  de  Microservices  começou  a  ganhar  destaque 
[3] especialmente no que se referia a escalabilidade de sistemas [4]. 
A  Arquitetura  baseada  em  Microsserviços  (Microservices-Based  Architecture, 
MBA) prezava pelo desenvolvimento de pequenos serviços que se concentravam em um 
único  contexto  de  negócio  [5],  criando  um  código  fracamente  acoplado  e  altamente 
coeso.  Assim,  possibilitaram  a  criação  de  uma  boa  modularidade  no  código  base  e 
permitiam  enfrentar  os  problemas  de  escalabilidade  que  dificultavam  as  alterações  ou 
adições de novas funcionalidades nas soluções que eram desenvolvidas. 
Os  benefícios  do  uso de MBAs chamaram bastante atenção para pesquisadores e 
desenvolvedores,  sendo  cada  vez  mais testados e comprovados.  Assim, tomou-se como 
uma  boa  ideia  a  aplicação  dos  conceitos  dessa  arquitetura  no  grupo  de  Frontend  [1], 
originando  um  estilo  arquitetural  que  faria  a  decomposição  de  uma  aplicação  frontend 
maior  em  menores  unidades  segmentadas  por  funcionalidade  e passaria a ser conhecida 
como a arquitetura de micro frontends [6]. 
Algumas  poucas  soluções  tentaram  abstrair  o  processo  de  integração  dessa 
arquitetura,  sendo o framework single-spa, atualmente, o mais conhecido e utilizado [7]. 
Após  estudos  de  exemplos  e  da  documentação,  foi  passível  de  identificação  a 
obrigatoriedade  de  utilização  de  um  plugin  específico  para  cada  tipo  de  tecnologia 
frontend  existente  nos  fragmentos  e  que  serviria  para  a  realização  do  controle  de  ciclo 
de  vida  e  integração  com  a  aplicação  contêiner.  Esse  plugin  só  reconhece  aplicações 
desenvolvidas  no  lado  de  cliente,  impõe  restrição  às  tecnologias  legado  que  eram 
desenvolvidas  no  lado  do  servidor  e  acaba  descentralizando  a  lógica  de  configuração 
das micro aplicações. 
Diante  do  exposto,  trata-se  como  objetivo  geral  deste  trabalho  desenvolver uma 
ferramenta  que  abstraia  o  processo  de  integração  de  micro  frontends  sem  obrigar  a 
instalação  de  dependências  obrigatórias,  como  os  plugins  do  single-spa.  Assim, 
facilitando o desenvolvimento de aplicações que desejem utilizar este tipo de arquitetura 
e ampliando o suporte a mais tecnologias. 
 

Dado  o  acumulado  de  referencial  teórico,  estruturada  a  metodologia  de 


desenvolvimento  e  obtidos  os  resultados,  é  realizada  uma  análise  da  construção  da 
ferramenta e da aplicabilidade da solução em relação aos seus objetivos específicos. 
O  trabalho  está  estruturado  da  seguinte  forma:  seção  2  descreve  o  contexto  no 
qual  está  envolvido  o  estudo;  seção  3  informa  os  procedimentos  referentes  à 
metodologia  de  trabalho  aplicada  para  conduzir  a  produção  dessa  ferramenta;  seção  4 
relata  os  resultados  do  desenvolvimento  da  solução;  seção  5  apresenta  uma  discussão 
dos  resultados  encontrados;  seção  6  traz  as  conclusões  deste  trabalho  e  aponta  as 
direções futuras. 

2. Contexto 
Nas  subseções  seguintes  serão  descritos  os  fundamentos  teóricos  que  deram  suporte  a 
concepção da ferramenta. 

2.1. Arquitetura monolítica 


Segundo  Krishnamurthy,  uma  arquitetura  monolítica  descreve  uma  aplicação  de 
“software”  de  camada  única,  onde  todos  os  serviços  e  componentes  estão  combinados 
em uma única solução [2]. 
Uma aplicação monolítica é aquela que usa uma única base de código para servir 
a  vários  serviços  e  “interfaces”  diferentes,  como  REST,  APIs  e  páginas  HTML.  Ainda 
hoje,  é  considerada  a  forma  padrão  para  começar  a  desenvolver  aplicações.  Uma  única 
base  de  código  facilita  o  desenvolvimento,  implantação  e  escalonamento  do  aplicativo, 
desde que o tamanho seja relativamente pequeno [19]. 
A  maioria  dos  aplicativos  pode ser bastante simples no início, mas à medida que 
o  tempo  e  a  aplicação  cresce,  o  mesmo  acontece  com  sua  complexidade.  Uma maneira 
típica  de  lidar  com  isso  é dividindo o aplicativo em diferentes camadas: uma camada de 
interface de usuário (IU), uma camada de serviço e um acesso a dados. 
No  entanto,  conforme  o  tamanho  do aplicativo e da organização cresce, também 
crescem  as  diferentes  camadas  da  aplicação.  A  menos  que  se  dê  muita  atenção  à 
arquitetura  e  qualidade  da  base  de  código,  é  muito  provável  que  a  qualidade  das 
diferentes  camadas  se  deteriore.  A  deterioração  acontece  devido  aos  requisitos  de 
negócios  que  forçam  desenvolvedores  a  fazer  soluções  que  não  são  ideais.  Como  o 
tamanho  da  base  de  código  cresce  e  a  qualidade  da  base  de  código  se  deteriora,  fica 
mais  difícil  adicionar  novos  recursos  e  modificar  recursos  antigos  porque  o 
desenvolvedor  tem  que  encontrar  o  lugar  correto  para  aplicar  essas  mudanças.  Isso 
resulta em ciclos de desenvolvimento mais lentos. 

2.2. Arquitetura de microsserviços 


Como  solução  para  mitigar  os  problemas  descritos  na  seção  anterior,  surgiu  em  2012 a 
arquitetura baseada em microsserviços. 
Essa  arquitetura  se  define  pela  construção  de  pequenos  serviços  que  se 
concentram  em  um  único  contexto  de  negócio.  Por  exemplo, um microsserviço poderia 
lidar com a criação de pedidos e outro microsserviço poderia lidar com a criação de uma 
 

nota fiscal referente ao pedido. Esses dois serviços têm suas bases de código separadas e 
se  houver  necessidade  de  comunicação  entre  eles,  a  comunicação  é  feita  por  meio  das 
APIs [19]. 
Devido  ao  pequeno  tamanho  e  foco  em  apenas  um  contexto  de  negócio,  os 
microsserviços  tornam  possível  alcançar  uma  boa  modularidade  na  base  de  código.  O 
objetivo  é  ter  serviços  fracamente  acoplados  e  altamente  coesos,  para  assim  sua 
simplicidade  tornar  a  modificação  e  adição  de  funcionalidades  relativamente  rápidas  e 
diminuir os ciclos de desenvolvimento. 
Empresas  como  Amazon,  LinkedIn  e  Netflix  fizeram  a  transformação  de  suas 
camadas  de  serviço  em  microsserviços.  Suas  experiências  positivas  e  de  longo  prazo 
com  este  estilo  de  arquitetura  atraiu  o  interesse  de  muitas  outras  empresas  e 
desenvolvedores. 

2.3. Arquitetura de micro frontends 

2.3.1. Definição 
Mesmo  com  a  evolução  arquitetural  dos  últimos  anos  e  redução  de  limitações  de 
grandes  backends  e  monolíticos,  as  bases  de  código frontend continuavam complexas e 
dificilmente escaláveis [6]. 
Dado  esse  contexto,  foi  imaginado  como  se  tirar  proveito  dos  benefícios  de 
modularização  e  escalabilidade  presentes  na  arquitetura  de  microsserviços  e  replicar 
seus efeitos no frontend. Desse “mix” foi originada a arquitetura de micro frontends. 
Cam  Jackson  define  a  arquitetura  como  um  “estilo”  no qual aplicações frontend 
são entregues de maneira independente e são compostas em uma aplicação maior [6]. 
Krishnamurthy, por sua vez, descreve o micro frontend como uma abordagem de 
microsserviços,  porém  aplicado  no  frontend,  onde  a  ideia  é  decompor  a aplicação web 
em unidades menores e segmentadas por funcionalidade [20]. 
Yang  et  al.  [20]  dizem  que  a  ideia  do  micro  frontend  é  tratar  uma  aplicação 
web  como  uma  combinação  de  recursos  onde  cada  time  cuida  de  uma  parte  desta 
aplicação e atende a um negócio ou função específico. 
Se  comparada  a  orientação  de  arquitetura  de  “web  ​mashups”​,  definida  como 
aplicação  que  combina  conteúdos  (como  dados  e  código)  de  várias  fontes  em  uma 
experiência  integrada  para  um  usuário  [18],  a  diferença  estaria  no  controle  e 
direcionamento  das  aplicações  externas  presentes  na  aplicação  contêiner.  A  arquitetura 
de  micro  frontends  dita  que  a  equipe  de  desenvolvedores  deve  ter  total  controle  de 
acesso  a  escrita  do  código  fonte  das  micro  aplicações,  e  estas  devem  na  maioria  das 
vezes  limitar  a  liberação  de  acesso  a  uma  única  origem  (a  da  aplicação  contêiner). 
Enquanto  isso,  os  “web  ​mashups”  utilizam  artefatos  públicos  que  permitem  acesso  de 
qualquer  tipo  de  origem  e  que  os  desenvolvedores  em  suma  maioria  não  terão controle 
de acesso a escrita do código fonte das micro aplicações. 
Cada  micro  aplicação  deve  ser  implementada  de  forma  autônoma,  modular  e 
bem  delimitada,  sendo  possível  alcançar  uma  evolução  independente  [8].  Assim, 
 

alterações  de  tecnologias  antigas  deixam  de  ser  dependentes  de  uma  reescrita  integral 
do código base. 
Podemos  reunir  as  ideias  principais  da  arquitetura  de  micro  frontends  nos 
seguintes tópicos [8]: 
● Modelagem em torno de domínios de negócio; 
● Abstração de detalhes de implementação; 
● Deployments independentes; 
● Isolamento de falhas. 

2.3.2. Parâmetros de orientação 


Dada  a  definição  e  ideias  centrais,  é  importante  entender  que  a  arquitetura  de  micro 
frontends  apresenta  diversas  formas  de  implementação  que  variam  de  acordo  com 
alguns parâmetros de orientação. Estes parâmetros irão definir seu modelo de separação, 
composição / renderização e comunicação. 

2.3.2.1. Separação  
O  parâmetro  de  separação  refere-se  a  distribuição  do  modo  de  exibição  e  ao  escopo  de 
trabalho dos times dentro de cada fragmento. As comuns escolhas de discussão são: 
● Separação horizontal, com múltiplos micro frontends por página; 
● Separação vertical, com apenas um micro frontend por página. 

Figura 1. Separação horizontal


 

Figura 2. Separação vertical 

2.3.2.2. Composição 
Por  sua  vez,  a  composição  refere-se  à  forma  de  renderização  da  aplicação.  As  comuns 
escolhas de discussão estão nas seguintes opções: 
● Composição no lado do cliente; 
● Composição central; 
● Composição no lado do servidor. 

Figura 3. Representação visual das técnicas de composição


A  composição  realizada  no  lado  do  cliente  sugere  que  a  aplicação  contêiner 
carregue  todos  os  seus  micro  frontends  diretamente  do  Content  Delivery  Network 
(CDN),  uma  rede  de distribuição de conteúdo para entregar a página a partir do servidor 
mais  próximo  do  usuário,  ou  de  sua  origem,  caso  ainda  não  tenha  sido  guardado  em 
cache,  a  partir  de  um  ponto  de  entrada  JavaScript.  Assim,  o  contêiner  consegue 
 

adicioná-los dinamicamente aos nós do ​Document Object Model (DOM), em caso de ser 
um  HTML,  ou  inicializar  a  aplicação  JavaScript. Uma outra possibilidade é a utilização 
de iframes. 
Já  utilizando  a  composição  central,  o  conteúdo  da  página  será  montado  e 
armazenado  em  múltiplos  CDN  que  utilizam  um  tipo  de  Extensible  Markup  Language 
(XML)  chamado  ​Edge  Side  Include  (ESI)  que  possibilitará  a  escalabilidade  da 
infraestrutura  da  aplicação  provida  pela  exploração  de  pontos  de  CDN  espalhados  pelo 
mundo,  assim  aumentando  de  capacidade  de  hosting  do  data  center  comparada  a  uma 
aplicação  comum. Porém, uma das desvantagens é que a utilização do ESI não é feita da 
mesma  forma  para  cada  CDN  e,  portanto,  uma  estratégia  multi-CDN  poderia  resultar 
em vários re-trabalhos de implementação [10]. 
Por  sua  vez,  a  composição  no  lado  do  servidor  detém  seu  conteúdo 
primariamente  de  sua  origem  e  armazena  a  informação  no  CDN,  servindo  ao  cliente  a 
tela final em tempo de execução ou compilação. 

2.3.2.3. Comunicação 
A  comunicação  entre  micro  frontends  ocorrerá  de  acordo  com  o  modelo  de  separação 
escolhido.  No  caso  da  separação  horizontal,  um  método  é  a  utilização  de  disparadores 
de  evento  providos  pelo  browser ou por objetos construídos pelo usuário dentro de cada 
micro  frontend.  Dessa  maneira,  quando  um  fragmento  emitir  um  evento,  o  outro 
conseguirá  obter  a  informação  a  partir  de  subscrições  realizadas  naquele  evento  em 
específico. Outras propostas de utilização são os eventos customizáveis, que são visíveis 
apenas nos contextos de janela em que foram emitidos. 

Figura 4. Comunicação entre micro frontends


 

Figura 5. Fluxo de requisição da aplicação


Para  a  separação  vertical  poderá  ser  utilizada  a  passagem de variáveis via query 
string  ou  suporte  das  ferramentas  de  armazenamento  nativas  do  navegador,  como 
Localstorage, Sessionstorage, Cookies, IndexedDB e outros. 

2.4. Single-SPA 
Atualmente,  a  biblioteca  single-spa  é  uma  das  principais  ferramentas  construídas  em 
JavaScript,  de  código  aberto,  para  construção  de  interfaces  de  usuário  na  web  que 
desejem  utilizar  a  arquitetura  de  micro  frontends.  Foi  desenvolvido  pelo  grupo Canopy 
com  o  objetivo  de  reunir  vários  micro  frontends  em  uma  única  aplicação.  Hoje,  o 
single-spa é utilizado por diversas companhias como Canonical, Zup, Scania e outras. 
Uma  aplicação  desenvolvida  com  o single-spa consiste na criação de um projeto 
contêiner e vários outros projetos de diferentes tecnologias. 
Logo  após  os  primeiros  estudos  de  exemplos  e  da documentação da ferramenta, 
foi  percebida  a  seguinte  condição:  ​Todas  as  micro  aplicações  desenvolvidas  eram 
obrigadas  a  utilizar  um  plugin  específico  que  desse  suporte  a  sua  stack  de 
desenvolvimento,  permitindo  a  configuração  dos  métodos  de  ciclo  de  vida  e  o 
integrando  a  aplicação  contêiner​.  Esse  plugin  só  considera  como  artefatos  de  micro 
aplicações  as  ferramentas desenvolvidas com conteúdo renderizável no lado do cliente e 
que  descentraliza  parte  do  processo  de  configuração  de ciclo de vida e integração. Com 
isso,  dificulta  a  utilização  da  tecnologia  em  ferramentas  antigas  que  majoritariamente 
trabalhavam  com  renderização  no  lado  do  servidor  e  que  hoje  almejam  realizar  a 
migração de seu sistema para alguma solução mais moderna. 
É  dessa  identificação  de  suporte  restritivo,  descentralização  de  configuração  e 
pequeno  acervo  de  soluções  atacando  este  tema  que nasce como objetivo deste trabalho 
 

o  desenvolvimento  de  uma  solução  que  seja  capaz  de  abstrair  a  integração  dos 
fragmentos  em um único contêiner sem a instalação de dependências obrigatórias, como 
os  plugins,  nos  fragmentos,  focando  em  um  tipo  de  construção  que  dê  às  micro 
aplicações  uma  maior  liberdade  de  escolha  de  tecnologias  e  facilite  a  configuração  de 
aplicações com esse tipo de arquitetura. 

3. Metodologia de trabalho 
Este  trabalho  compreende  uma  proposta de desenvolvimento prática realizada com base 
nas  diretrizes  teóricas  compreendidas  na  seção anterior. Assim, nas subseções seguintes 
serão  descritos  os  passos  práticos  que  auxiliaram  o  processo  de  desenvolvimento  e 
validação da ferramenta.  

3.1. Escolha de parâmetros orientadores 


Essa  etapa  compreende  as  escolhas  referentes  aos  métodos  de  separação, composição e 
comunicação  dos  micro  frontends  a  partir  dos  problemas  citados  e  objetivos  a  serem 
atingidos. 
Devido  aos  itens  desejáveis  de  entrega,  a  necessidade  de  baixo  tempo  de 
implementação  e  conhecimento  prévio  de  tecnologias  específicas  do  autor,  os 
orientadores de implementação escolhidos foram: ​a separação vertical, composição no 
lado  do  cliente  por  auxílio  de  iframes  e  comunicação  entre  micro  frontends 
auxiliada por evento no modelo publish / subscribe​. 
Uma  vez  que  os  parâmetros  orientadores  foram  escolhidos,  foi  realizada  uma 
sessão de brainstorming. 

3.2. ​Brainstorming
O  propósito  de  se  realizar  o  “brainstorming”,  técnica  utilizada  para  propor  soluções  a 
um  problema específico, foi garantir uma maior diversidade de opções para a escolha da 
solução final. 
Dado  esse  contexto,  foram  pensadas  algumas  arquiteturas.  As  soluções  que 
demonstraram  estar  fora  do  esperado,  não  contendo  todos  os  parâmetros  orientadores 
definidos  ou  que  não  conseguiriam  ser  executados  em  tempo  hábil,  foram  eliminadas, 
garantindo  assim  a  permanência  das  que  realmente  estavam  alinhadas  à  proposta.  Ao 
final  desse  processo,  dentre as opções pensadas, a de codinome Roll Cake foi escolhida. 
A  relação  completa  das  soluções  pensadas  e  excluídas pode ser encontrada no apêndice 
A. 

3.3. Solução
A  solução  de  codinome  Roll  Cake  contemplaria  três  módulos  JavaScript  com 
responsabilidades  únicas  e  suas  próprias  interfaces  de  programação  de  aplicativos 
(API), sendo eles: 
● Roll Cake MF-Broker: um mediador de micro frontends; 
● Roll Cake Router: um mediador de rotas; 
● Roll Cake SPA: um renderizador de elementos e integrador de módulos. 
 

Figura 6. Solução Roll Cake 

3.3.1. Módulo MF-Broker 


O  módulo  mf-broker  recebe  esse  nome  por  atuar  como  um  middleware  entre  o  cliente 
web  e  os  vários  micro  frontends  da  aplicação,  assim  como  uma  arquitetura  broker  de 
mensageria.  O  mesmo  deverá  identificar quais fragmentos deverão ser inseridos em tela 
e  preparar  um  ambiente  de  comunicação  e  armazenamento  de  dados  totalmente 
compartilhável  entre  eles  e  a  aplicação.  Pode-se,  inclusive,  considerar  este  módulo 
como o artefato de maior valor agregado do projeto. 
Importante  citar  que  este  módulo  foi  estruturado  focado,  principalmente,  na 
liberdade  e  facilidade  de  implementação  para  outras  soluções  de  SPA  Frameworks, 
permitindo  ao  usuário  utilizar  o  mediador  de  micro  frontends  em  uma  aplicação 
contêiner com qualquer tecnologia desejada.
 

Figura 7. Arquitetura de controle de micro frontends 

Figura 8. Arquitetura de comunicação de micro frontend 

3.3.2. Módulo Router 


O  módulo  router  é  o  responsável  por  realizar  a  identificação  e  controle  de  rotas  da 
aplicação  no  lado  do  cliente.  Assim,  o  mesmo  deverá  ao  contar  com  eventos  de 
navegação,  manipulação  de  histórico  de  navegação,  e  cenários  de  identificação  de 
mudança  de  rota  na  qual  deverá  emitir  um  evento  de  notificação  contendo  um  artefato 
relacionado àquele endereço. 
 

Figura 9. Arquitetura do router

3.3.3. Módulo SPA 


Por  sua  vez,  o  módulo  do  SPA  será  o  responsável  pela  utilização  e  integração de todos 
os  módulos  anteriores,  juntamente  com  a  capacidade  de  renderização,  destruição  e 
atualização de elementos em tela. 
Seu  ciclo  deve  se  iniciar  com  a  observação  de  modificações  de  rota,  realizada 
pelo  módulo  router,  assim  identificando  qual  item  deve  ser  renderizado  em  tela  e 
realizando a ação de inserção. 
Logo  após  a  renderização  do  elemento,  o  módulo  mf-broker  irá  identificar  se  o 
item  é  um  custom  element  reconhecido  por  sua  lógica  de desenvolvimento e, caso seja, 
serão observados os atributos declarados na renderização do elemento e sua relação com 
os dados internos disponíveis no módulo. 
Confirmada  a  relação  entre  os atributos do elemento e os dados disponibilizados 
para  o  mf-broker,  será  estabelecida  uma  ponte  de  comunicação  com  o  SPA  para  a 
identificação  do  começo  e  término  do  processo  de  requisição  de  micro  frontends e será 
realizada  uma  solicitação de conteúdo do fragmento. Solicitação essa que, enquanto terá 
suas  trativas  sendo  realizadas,  fará  o  SPA  realizar  uma  sobreposição  de  tela  com  um 
componente de carregamento. 
Assim  que  a  requisição  for  finalizada,  o  SPA  removerá  a  sobreposição de tela e 
o  custom  element  terá  em  seu  conteúdo  o  elemento  de  iframe  disponibilizado  pelo 
módulo do mf-broker. 
 

Figura 10. Arquitetura do SPA com todos os serviços integrados 

3.4. ​Plano de distribuição


Pensando  na  disponibilização  gratuita  da  ferramenta  foram  escolhidos  canais  de 
distribuição  que  permitissem  alta  visibilidade  da  comunidade  de  desenvolvimento, 
acesso  à  ferramentas  de  inserção  e  inspeção  de  código,  quadro  de  problemas  e 
atividades e histórico de versões. Sendo as seguintes ferramentas selecionadas: 
● Github: Uma plataforma de hospedagem de código-fonte e arquivos; 
● Github Packages Registry: Um serviço de hospedagem de pacotes de software. 

3.5. ​Cenário de exemplificação


Para  demonstrar  o  funcionamento  da  solução,  foi  definido  a  construção  de  um  cenário 
de  exemplificação  que  tivesse  como  requisitos  obrigatórios  a  utilização  de  todas  as 
funcionalidades  providas  pela  API  da  ferramenta  a  ser  concebida,  fragmentos  de  pelo 
menos  3  tecnologias  de  frontend  distintas  e  que  possuíssem  ao  menos  um  pouco  de 
semelhança  visual  e  funcional  com  alguma  ferramenta  ou  serviço  muito  utilizado 
durante a data de publicação deste trabalho. 
Dado  esse  contexto,  o  cenário  de  exemplificação  escolhido  foi  o 
desenvolvimento  de  um  SPA  clone  do  serviço  de  streaming  musical  Spotify.  Serviço o 
 

qual  possui  uma  versão  desktop  que  utiliza  uma  arquitetura  de  micro  frontends  com 
forte  similaridade  aos  parâmetros orientadores da ferramenta proposta por este trabalho. 
Utilizando  um  modelo  de  separação  voltado  para  a  horizontalização  de  equipes, 
realização  da  composição  da  aplicação  no  lado  do  cliente  com  auxílio  de  iframes  e 
comunicação  por  eventos  no  modelo  publish  /  subscribe[8].  As  seguintes  Figuras  11  e 
12 representam as páginas do Spotify que esperam ser minimamente implementadas. 

Figura 11. Página de login do Spotify

Figura 12. Página do web player do Spotify 

4. Resultados 
Esta  seção  fornece  uma  descrição  funcional  dos  artefatos  implementados  a  partir  das 
diretrizes traçadas na seção anterior. 

4.1. Módulo MF-Broker 


O  módulo  mf-broker  foi  construído  sob  a  utilização  da  linguagem  de  programação 
JavaScript com o auxílio do gerenciador de pacotes npm e as seguintes bibliotecas:  
● Babel:  realiza  a  transpilação  do  código  para  versões  minificadas  e  de  maior 
suporte nativo a navegadores;  
● Eslint: verifica de boas práticas na escrita de código;  
● Lodash: abstrai funções comumente utilizadas no JavaScript; 
● Rxjs:  disponibiliza  uma  interface  de  criação  de  eventos  de  comunicação do tipo 
publish / subscribe. 
 

Seis artefatos foram necessários para realizar seu funcionamento, sendo eles:  
● EventBus:  uma  classe  que  representa  a  interface  de  comunicação  no  modelo 
publish / subscribe;  
● GlobalStore:  uma  classe  responsável  pelo  compartilhamento  e  persistência  de 
dados; 
● Microfrontend:  uma  classe  responsável  pela  identificação  e  tratamento  de 
Custom Elements com a tag “rollcake-microfrontends”; 
● RollCakeMFBroker:  uma  classe  dedicada  a  integração  de  serviços  internos  e 
transmissão de eventos; 
● Um armazenador de constantes para re-utilização de variáveis; 
● Um arquivo exportador de itens. 
Dentre  os  itens  citados,  apenas  dois  estão  disponíveis  para  utilização  pública:  a 
classe  RollCakeMFBroker  e  as  constantes  referentes  ao  nome  da  variável  de  janela 
criada  pelo  módulo,  ao  nome  da  Custom  Tag  referente  aos  micro  frontend  e  ao  nome 
dos eventos públicos cabíveis de recebimento. 
A  partir  da  instalação  do  módulo,  se  o  usuário  quiser  utilizar  a  ferramenta  terá 
que  realizar  a  configuração  da  classe  RollCakeMFBroker.  A  classe possuirá apenas um 
parâmetro  de  entrada  do  tipo  lista  de  objetos  que  deverá  armazenar  as  declarações  de 
micro  frontends  que  desejam  ser  atribuídas  a  aplicação.  Nesse  objeto  devem  ser 
informados os atributos name e address. 
Tabela 1. Exemplo de declaração e inserção de parâmetros da classe 
RollCakeMFBroker 

import { RollCakeMFBroker } from '@rollcakejs/rollcake-mf-broker'; 


 
const MFBroker = new RollCakeMFBroker([{ 
name: 'react-bucket', 
address: 'https://localhost:3000' 
}]); 

Após  realizada  a  instância  da  classe,  o  construtor  disponibiliza  ao  usuário  um 
método  de  inicialização  chamado  init  que  define  como  atributo  interno  o  objeto  que 
conterá  a  lista  de  buckets  e  instância  as  classes  EventBus  e  GlobalStore  para, 
posteriormente, compartilhá-los através das variáveis de janelas. 
Tabela 2. Exemplo de execução do método init 

MFBroker.init(); 

Criada  a variável de janela, a classe Microfrontend passa a detectar a inserção de 
elementos  com  a  tag  “rollcake-microfrontend”  no  HTML  do  cliente.  A  partir  de  sua 
detecção,  é  lido  o  parâmetro  name  e  dele  é  tentado  achar  alguma  referência  com  a 
declaração  dos  buckets  feitas  na  instância  da  classe  RollCakeMFBroker. Se passível de 
pareamento,  será  criada  uma  resposta  encapsulada  em  um  iframe,  que  conterá  uma 
cópia  da  variável  de  janela  compartilhável previamente descrita no parágrafo anterior, e 
será  feita  uma  requisição  para  adquirir  o  HTML  content  do  address  encontrado.  Se  a 
 

requisição  for  respondida  com  sucesso,  ela  será  integrada  ao  elemento  encapsulador  e 
enviada ao cliente. Caso contrário, o processo encerra-se. 
Tabela 3. Exemplo de custom element identificável pelo módulo 

<rollcake-microfrontend name=”react-bucket”> 
</rollcake-microfrontend> 

Tabela 4. Exemplo de utilização das variáveis de janela injetadas pelo módulo 

// EventBus 
window.RollCake.bus.publish(eventName,payload); 
window.RollCake.bus.subscribe(eventName, callback); 
 
// GlobalStore 
window.RollCake.store.getState(stateName); 
window.RollCake.store.setState(stateName, newState); 

4.2. Módulo Router 


O  módulo  router  foi construído sob as mesmas escolhas de tecnologias e ferramentas da 
seção anterior.  
Necessitou-se de apenas três artefatos para sua implementação, sendo eles:  
● RollCakeRouter: Uma classe responsável pela identificação e controle de rotas;  
● Um armazenador de constantes; 
● Um arquivo exportador de itens. 
Dentre  os  itens  citados, dois foram disponibilizados para utilização do usuário: a 
classe RollCakeRouter e a constante referente aos modos de navegação implementados. 
No  construtor  da  classe  RollCakeRouter  é  recebível  como  parâmetro de entrada 
um  tipo  objeto  que  deverá  conter  dois  atributos: routes e mode. O atributo routes é uma 
lista  de  objetos  do  tipo  route,  que  possui como atributos internos o path e o item, o qual 
o  path  é  o  parâmetro  de  orientação  de  exibição  e  o  item  é  o  valor  a  ser  exibido. 
Enquanto  isso,  o  mode  é  um  atributo  tipo  texto  que  terá  uma  variação  de  dois  valores: 
hash  e  history.  A  diferença  entre  os  dois  modos  é  a  interpretação  do  navegador  para  o 
registro  de  roteamento  e  uma  pequena  diferença  visual,  possível  de  ser  vista  na  Tabela 
6. 
Tabela 5. Exemplo de declaração e inserção de parâmetros da classe 
RollCakeRouter 

import { RollCakeRouter, NAVIGATION_MODE } from '@rollcakejs/rollcake-router'; 


import ReactPage from './pages/ReactPage'; 
 
const Router = new RollCakeRouter({ 
routes: [ 
{ path: '/react', item: ReactPage } 
], 
mode: NAVIGATION_MODE.HISTORY 
}); 
 

Tabela 6. Diferença de URI entre os modos de roteirização 

Modo  URI 

Hash  https://server:port/#/home 

History  https://server:port/home 

Após  instância  de  sua  classe,  o  atributo  routes  é registrado como valor interno e 


o  atributo  mode  é  verificado  para,  a  partir  de seu valor, alterar as funções de navegação 
e  localização  da rota. Também, ocorre a disponibilização de um método de inicialização 
chamado  init,  para  realizar  a  identificação  de  mudança  de  rota  e  retornar  um  callback, 
contendo o path e o item da nova rota para seu watcher realizar a tratativa deste evento. 
Tabela 7. Exemplo de declaração e utilização do método de init 

Router.init((props) => { 
console.log(props.path); 
console.log(props.item); 
}); 

4.3. Módulo SPA 


Assim  como  o  módulo  anterior,  o  SPA  foi  construído  sob  as  mesmas  escolhas  de 
tecnologias  e  ferramentas  da  seção  referente  ao mf-broker, porém com um código fonte 
mais  complexo  devido  aos  métodos  de  integração  com  os  outros  módulos  e  a  sua 
responsabilidade  de  renderização  de  elementos,  necessitando  de  sete  artefatos  para 
execução de todas as suas tarefas:  
● RollCakeSpa:  uma  classe  responsável  pela  inicialização  dos  outros  módulos  e 
integração com as funções do SPA; 
● Page: uma classe responsável pela renderização de páginas; 
● Element: uma classe responsável pela renderização de elementos; 
● createPage: uma função responsável pela criação de páginas; 
● createElement: uma a função responsável pela criação de elementos;  
● Um compartilhador de constantes;  
● Um exportador de artefatos deste e dos outros módulos. 
  Os  itens  públicos  disponibilizados  para  o  usuário  final  são:  a  classe 
RollCakeSpa,  a  classe  RollCakeRouter,  a  classe  RollCakeMFBroker,  as  funções  de 
criação de página e elemento, e algumas constantes. 
Para  a  utilização  do  módulo  é  necessária  a  implementação  da  classe 
RollCakeSpa.  Nela  é  feito o recebimento de três parâmetros obrigatórios e um opcional, 
sendo esses: o MFBroker, router, entryDOMNode e o loadingContent (opcional). 
 
 
 
 

Tabela 8. Exemplo de declaração e inserção de parâmetros da classe 


RollCakeSpa 

import { RollCakeMFBroker, RollCakeRouter, RollCakeSpa, NAVIGATION_MODE } from 


'@rollcakejs/rollcake-spa'; 
import ReactPage from './components/ReactPage'; 
import './global.css'; 
 
const MFBroker = new RollCakeMFBroker([{ 
name: 'react-bucket', 
address: 'https://localhost:3000' 
}]); 
 
const Router = new RollCakeRouter({ 
routes: [{ 
path: '/react', 
item: ReactPage 
}], 
mode: NAVIGATION_MODE.HISTORY 
}); 
 
new RollCakeSpa(MFBroker, Router, document.getElementById('root')); 

Ao  ser  instanciado,  ele  realiza  a  chamada  de  inicialização  das  classes 
RollCakeMFBroker e RollCakeRouter. 
Uma  vez  que  o  módulo  MF-Broker  seja  inicializado,  ele  realizará  a 
disponibilização  das  mediações  de  micro  frontends  e  a  interface  de  comunicação  entre 
elas.  Posteriormente,  a  partir  da  interface  de  comunicação,  o  SPA  passará  a  escutar 
eventos  de  requisição,  para  fazer  a  sobreposição  de  tela  com  o  conteúdo  do  atributo 
loadingContent,  e  solicitação  de  navegação,  para  requisitar  ao  módulo  router  uma 
navegação forçada. 
Logo  em  seguida,  o  router  é  inicializado  para  detecção  de  mudança  de  rotas. 
Uma  vez  que  algo  seja  detectado,  ele  fará  uma  verificação  de  existência  perguntando a 
seus  atributos  internos  se  existe alguma página atualmente visível para o usuário e, caso 
exista,  vai  deletá-la  para  solicitar  a  renderização  do novo item. Item este que deverá ser 
do  tipo  função  e  ter  como  retorno  referência  ao  artefato  createPage  disponibilizada 
publicamente por este módulo. 
O  createPage  irá  realizar  a  criação  da  classe page que, ao ser instanciada, irá em 
seu  construtor  fazer a atribuição de valores internos e realizar a execução de métodos de 
renderização  e  destruição  que  irão  ativar  funções  internas ao ciclo de vida da aplicação. 
No  caso  do  método  render  é  disparada  a  ativação  dos  atributos  do  tipo  função  onInit  e 
content,  o  qual  o  content  deverá  ter  como  retorno  obrigatório  uma  instância  da  classe 
element que será responsável pela inserção de conteúdo no DOM. 
 
 
 
 

Tabela 9. Exemplo de declaração e inserção de parâmetros da função 


createPage 

import { createPage } from '@rollcakejs/rollcake-spa'; 


import ReactBucket from ‘../components/ReactBucket’; 
 
const ReactPage = () => createPage({ 
onInit: function() { console.log('initialized!') }, 
onDestroy: function() { console.log('destroyed!') }, 
onUpdate: function() { console.log('updated') }, 
content: function() { 
return ReactBucket() 

}); 
 
export default ReactPage; 

Tabela 10. Exemplo de declaração e inserção de parâmetros da função 


createElement 
import { createElement, CUSTOM_ELEMENT_TAG} from '@rollcakejs/rollcake-spa'; 
 
const ReactBucket = () => createElement({ 
tag: CUSTOM_ELEMENT_TAG.MICROFRONTEND, 
attr: { 
name: 'react-bucket' 

}); 
 
export default ReactBucket; 

Um  ponto  importante  da  exemplificação  da  Tabela  12  é  a  definição  de  um 
elemento  de  micro  frontends.  Para  seja realizada uma mediação do broker com sucesso, 
é  necessário  solicitar  a  criação  de  um  elemento  que  possua  em  sua  declaração  de  tag 
com  o  valor  “rollcake-microfrontend”  e  no  atributo  attr  adicionar  a  chave  “name”  com 
um  valor  correspondente  ao  bucket  declarado  na  referência  de  configuração  da  classe 
RollCakeMFBroker. 

4.4. Plano de distribuição 


Para  a  disponibilização  do  conteúdo  deste  trabalho  foi  criada  uma  organização  na 
plataforma  Github chamada rollcakejs. Essa organização contém os repositórios dos três 
módulos  JavaScript  com  controle  de  versão  feito  pela  ferramenta  git  e  disponibiliza  a 
utilização  do  pacote  com  auxílio  do  Github  Package  Registry.  O  link  de  acesso  para  a 
organização é o: ​https://github.com/rollcakejs​. 

4.5. Cenário de exemplificação: Spotify Clone 


O  Spotify  Clone,  foi  construído  sob  a  implementação  de  um  mono-repositório 
majoritariamente  com  um  código  fonte  desenvolvido  em  JavaScript  e  auxiliado  pelo 
gerenciador de pacotes yarn. 
 

Figura 13. Estrutura de organização do mono-repositório / pasta root


Na  pasta  root,  é  feita  a  declaração  de  uma  package.json  independente  para  a 
instalação  e  configuração  do  pacote  lerna,  o  qual  ajudará  a  realizar  a  manutenção  e 
automação  de  tarefas  dentro  do  repositório,  além  de  configurar  o  workspaces  (uma 
feature  disponibilizada  pelo  gerenciador  de  pacotes  para  agrupar  dependências  em 
comum). Desse modo, é possível executar simultaneamente todas as aplicações contidas 
no projeto bastando digitar o comando lerna run start:dev em um terminal de comando. 
É  importante  citar  que  para  acelerar  o  desenvolvimento  de  novos  projetos  com 
essas  ferramentas  e  estruturação  foi  disponibilizado  na  organização  rollcakejs,  no 
Github,  um  repositório  contendo  um  template  inicial  para  a  abstração  de todo processo 
de preparo do ambiente de desenvolvimento. 

4.5.1. Aplicação contêiner 


Na  pasta  app  estará  armazenada  a  aplicação  contêiner  que  fará  a  configuração  e 
integração  de  todos  os  micro  frontends,  ou  seja,  é  onde  estará  concentrada  a  solução 
desenvolvida nesta proposta de experimentação. 
Assim  como  todas  as  outras  aplicações  presentes  no  repositório,  essa  pasta  terá 
um  package.json  próprio  para  o gerenciamento de dependências, controle de publicação 
e criação de scripts. 

Figura 14. Estrutura de organização da camada app


Para  construção  do  ambiente  de  desenvolvimento,  foram  utilizados  os  pacotes 
babel,  webpack  e  webpack-dev-server.  Toda  concentração  de  esforços  de  controle  e 
configuração  serão  realizados  no  arquivo  webpack.config.js,  o  qual  deverá  conter 
loaders  e  plugins  para  realização  de  leitura  e  tratamento  de  arquivos  css,  assim  como 
deverá  realizar  a  transpiração,  minificação  de  código  JavaScript  para  aumento  de 
cobertura  de  suporte  a  navegadores  e  fazer  a  indexação  dos  arquivos  encontrados  na 
pasta  public  a  um  servidor  local.  Importante  ressaltar  que  entre  os  arquivos 
disponibilizados  na  pasta  public,  deverá  estar  um  arquivo  index.html  que  conterá  um 
script  tag  com  referência ao arquivo index.js da pasta src e uma div tag com um atributo 
 

id de qualquer valor que será utilizado como referência para o entryDOMNode da classe 
RollCakeSpa. 
Finalizado  o  pré-setup  do  ambiente  é  possível  focar  na  estruturação  e 
implementação  da  pasta  src  com  o  arquivo  index.js  e  seus  derivados,  criando  os 
seguintes  artefatos:  mf-broker.config.js,  router.config.js,  global.css,  pasta  components, 
pasta pages e o próprio index.js. 

Figura 15. Estrutura de organização da pasta src


O  arquivo  mf-broker.config.js  contém  como  pacote  de  referência  a  solução 
MF-Broker,  trazendo  consigo  todos  os  registros  referentes  aos  micro  frontends  e 
realizando a exportação do objeto RollCakeMFBroker. 
Tabela 11. Exemplo de arquivo mf-broker.config.js 

import { RollCakeMFBroker } from '@rollcakejs/rollcake-spa'; 


 
const buckets = [ 

name: 'authentication-bucket', 
address: 'http://localhost:3000' 
}, 

name: 'menu-bucket', 
address: 'http://localhost:3001' 
}, 

name: 'player-bucket', 
address: 'http://localhost:3004' 
}, 

name: 'playlist-board-bucket', 
address: 'http://localhost:3003' 

]; 
 
export default new RollCakeMFBroker(buckets); 
 

O  arquivo  router.config.js  contém  como  pacote  de  referência  a  solução 


Roteador,  trazendo  consigo  todos os registros referentes às rotas e aos itens exibidos em 
tela e realizando a exportação do objeto RollCakeRouter. 
Tabela 12. Exemplo de arquivo router.config.js 

import { RollCakeRouter, NAVIGATION_MODE } from '@rollcakejs/rollcake-spa'; 


import AuthenticationPage from './pages/AuthenticationPage'; 
import DashboardPage from './pages/DashboardPage'; 
 
const routes = [ 
{ path: '/', item: AuthenticationPage}, 
{ path: '/dashboard', item: DashboardPage } 
]; 
 
export default new RollCakeRouter({ 
routes, 
mode: NAVIGATION_MODE.HISTORY 
}); 

A  pasta  pages  armazena  vários  folders  internos  com  arquivos  index.js  e 


index.css  que  estão  importando  estilizações  e  exportando  uma  constante do tipo função 
com  retorno  para  a  chamada  createPage,  constante  essa  que  deverá  ser  importada  e 
referenciada pelo arquivo router.config.js (como demonstrado no parágrafo anterior). 
Tabela 13. Exemplo de arquivo index.js de um page 

import { CONTEXT_ATTRIBUTE, createPage, PUBLIC_BUS_PUBLISH_EVENT_TYPE, 


WINDOW_VARIABLE } from ‘@rollcakejs/rollcake-spa’; 
import AuthenticatioMf from ‘../../components/AuthenticationMf’; 
import ‘./index.css’; 
 
const AuthenticationPage = () => createPage({ 
onInit: function() { 
const winVar= window[WINDOW_VARIABLE.ROLLCAKE]; 
const store = winVar[CONTEXT_ATTRIBUTE.STORE]; 
const bus = winVar[CONTEXT_ATTRIBUTE.BUS]; 
if (store.getState('authentication')) { 
bus.publish(PUBLIC_BUS_PUBLISH_EVENT_TYPE.NAVIGATE_TO, '/dashboard'); 
} else { 
bus.subscribe('authorized-user-callback', () => { 
store.setState('authentication'); 
bus.publish(PUBLIC_BUS_PUBLISH_EVENT_TYPE.NAVIGATE_TO, '/dashboard'); 
}); 

}, 
content: function() { 
return AuthenticatioMf(); 

}); 
 
export default AuthenticationPage; 
 

A  pasta  components  também  armazenará  vários  folders  internos  com  arquivos 


index.js  e  index.css  que  também  estão  importando  estilizações,  porém  exportando  uma 
constante  do tipo função com retorno para a chamada createElement. A ideia é que estes 
itens  possam  ser  utilizados  como  retorno  no  atributo  content  do tipo função encontrado 
como  parâmetro  de  entrada  na  chamada  do  artefato  createPage,  presente  nos  itens  da 
pasta pages. 
Tabela 14. Exemplo de arquivo index.js de um component 

import { createElement, CUSTOM_ELEMENT_TAG } from ‘@rollcakejs/rollcake-spa’; 


import ‘./index.css’; 
 
const AuthenticatioMf = () => createElement({ 
tag: CUSTOM_ELEMENT_TAG.MICROFRONTEND, 
attr: { 
name: 'authentication-bucket', 
class: 'microfrontend' 

}); 
 
export default AuthenticatioMf; 

Por  fim,  o  arquivo  index.js  faz  a  importação  dos  artefatos  de  alto  nível  como  o 
global.css,  que  registra  todas  as  estilizações  globais  da  aplicação,  o  router.config.js,  o 
mf-broker.config.js  e  a  classe  RollCakeSpa,  fazendo  assim  a  declaração  da  classe  e 
colocando alguns dos itens importados como parâmetros de entrada. 
Tabela 15. Exemplo de arquivo index.js 

import { RollCakeSpa } from ‘@rollcakejs/rollcake-spa'; 


import MFBroker from './mf-broker.config'; 
import Router from './router.config'; 
import LoadingOverlay from './components/LoadingOverlay'; 
import './global.css'; 
 
new RollCakeSpa(MFBroker, Router, document.getElementById('root'), LoadingOverlay); 

4.5.2. Micro frontends de autenticação 


O  módulo  de  authentication  é  o  primeiro  fazendo  referência  à  criação,  de  fato,  de  uma 
aplicação  que  se  tornará  um  Micro  frontend.  Ele  e  todos  os  próximos  módulos a serem 
discutidos estão presentes na pasta de micro-apps. 
Esse  fragmento  deverá  ser  responsável  por  realizar  toda  a  configuração  de 
autenticação  e  autorização  do  usuário.  Sua  tecnologia  de  desenvolvimento  frontend  foi 
o  Vue.js  [11],  sendo  utilizadas  as  dependências  comuns  a  projetos  vue  e  o 
spotify-web-api-node,  o  qual  estará  presente  na  maioria  dos  módulos  dos  fragmentos  e 
fará requisições para a api do Spotify. 
Após  toda  criação  do  ambiente  de  desenvolvimento  com  a  utilização  do  Vue 
CLI,  foram  configurados  alguns  componentes  básicos  e  definidas  duas  rotas:  login  e 
callback.  A  página  de  login  é  a  ferramenta  de  interação  virtual  do  usuário  que  deverá 
 

conter  semelhança  visual  com  a  página oficial de login do Spotify e um botão funcional 


que  abra  uma  janela,  solicite  as  credenciais  de  acesso  oficial  do  usuário  no  serviço  de 
streaming  musical  e  o  mande  para  a  página  de  callback.  Essa  página  deverá  retornar 
essa  credenciais  de  acesso  para  a  página  de  login,  onde  deverá  ser  posteriormente 
transmitido  para  a  aplicação  contêiner  pela  interface  de  comunicação  da  solução 
MF-Broker,  o  qual  será injetada em suas variáveis de janela quando estiver em modo de 
exibição Micro frontend. 
Tabela 16. Exemplo de verificação e envio de evento através da injeção de 
variável de janela do MF-Broker  

if (window.RollCake) { 
window.RollCake.bus.publish("authorized-user-callback", {accessToken: 
xXxXxXxXxXxXx}); 

4.5.3. Micro frontends de menu 


Por  sua  vez,  o  módulo  menu  é  uma  aplicação  que  terá  a  responsabilidade  de 
disponibilizar  ao  usuário  o  acesso  de  suas  playlist  no  Spotify  além  de,  futuramente, 
agregar métodos de navegação no SPA.  
Como  forma  de  contribuir  para  a  diversidade  de  ferramentas  utilizadas  na 
aplicação  contêiner,  sua  tecnologia  de  desenvolvimento  frontend  escolhida  foi  o 
Angular  [12].  Já  as  bibliotecas  de  suporte  foram  as  dependências  comuns  a  projetos 
angular e o spotify-web-api-node. 
Toda  configuração  e  estilização  do  fragmento  foi  realizado  nos  arquivos  de 
prefixo  app,  esperando-se  um  componente  interativo  com  semelhança  visual  ao  menu 
encontrado  na  página  oficial  do  WebPlayer  do  Spotify,  consumindo  dados  do  módulo 
anteriormente  apresentado  e,  principalmente,  disponibilizando  uma  lista  de  playlist  do 
usuário  que  poderá  ser  clicada  e,  posteriormente,  transmitida  para  a  micro-aplicação 
player pela interface de comunicação da solução MF-Broker. 
Tabela 17. Exemplo de obtenção do valor referente ao ao usuário autenticado 

if ((<any>window).RollCake){ 
const authorizedUser = 
(<any>window).RollCakeMFBroker.store.getState('authentication'); 

Tabela 18. Exemplo de envio de evento para reprodução da playlist selecionada 

(<any>window).RollCake.bus.publish('play-user-playback',context_uri); 

4.5.4. Micro frontends de quadro de faixas musicais 


Para  o  módulo playlist-board seu produto será uma aplicação com a responsabilidade de 
disponibilizar ao usuário um quadro de playlist recomendadas pelo Spotify.  
E,  novamente,  como  forma  de  contribuição  para  a  diversidade  de  ferramentas 
utilizadas  na  aplicação  contêiner,  a  tecnologia  de  desenvolvimento  frontend  escolhida 
 

foi  o  React  [13]  com  as  dependências  comuns  a  projetos  react  e,  novamente,  o 
spotify-web-api-node. 
Foram  criados  alguns  componentes  básicos  e  todos  foram  agrupados  em  um 
único  componente  pai.  Esse  componente  de  maior  nível  hierárquico  estaria  indexado  a 
página  inicial  da  micro-aplicação  que  teria  os  mesmos  propósitos  que  os  módulos 
anteriores:  interação  virtual  com  o  usuário  e  semelhança  visual  com  a  página oficial de 
WebPlayer  do  Spotify.  Portanto,  o  fragmento  deverá  consumir  os  dados  do  módulo  de 
autenticação  e,  principalmente,  disponibilizar  uma  lista  de  playlists  recomendadas,  que 
poderá  ser  clicada  e  posteriormente  transmitida  para  a  micro-aplicação  player  pela 
interface de comunicação da solução MF-Broker. 

4.5.5. Micro frontends de reprodução musical 


Dentro  do  módulo  player  será disponibilizada uma aplicação com a responsabilidade de 
oferecer  ao  usuário  o  reprodutor  musical  do  Spotify  dentro  do  navegador,  além  de 
realizar  o  consumo  de  eventos  dos  outros  micro  frontends  e  executar  as  ações 
requeridas.  
Sua  tecnologia  de  desenvolvimento  frontend  escolhida  foi  o  Svelte  [14]  e  teve 
com  suas  dependências  de  projeto  algumas  das  bibliotecas  mais  comuns  para  a 
construção  de  projetos  em  Svelte  e  a  dependência  mais  utilizada  entre  todos  os 
fragmentos: o spotify-web-api-node. 
Dentro  da  composição  de  seu  arquivo  de  configuração  principal  foi  feita  a 
integração  entre  os  serviços  de  requisição  disponibilizados  pela  biblioteca 
spotify-web-api-node e o SDK disponibilizado pelo próprio Spotify para implementação 
abstrata  das  funcionalidades  do  player.  Assim,  o  fragmento  deverá  consumir  os  dados 
do  módulo  de  autenticação,  integrar  o  SDK  e  as  requisições  da  biblioteca 
spotify-web-api-node,  além  de consumir os eventos providos do MF-Broker e efetuar as 
ações esperadas pelos outros micro frontends ou a própria aplicação principal. 
Tabela 19. Recebimento de evento para reprodução da playlist selecionada 

window.RollCake.bus.subscribe('play-user-playback', (context_uri) => { 


playMusic(); 
}); 

4.5.6. Resultado final 


Ao  final, todos os fragmentos conseguiram ser executados, independentemente de stack, 
e  exibidos  simultaneamente  na  aplicação  contêiner  sem  a  necessidade  de  instalação  de 
qualquer dependência obrigatória nos micro frontends. 
 

Figura 16. Diversidade tecnológica da aplicação final

Figura 17. Resultado alcançado do protótipo de desenvolvimento do Spotify 


Clone 

5. Discussão 

5.1. Cenário de exemplificação funcional com ressalvas 


O  cenário  de  exemplificação  construído  teve  uma  interface  fluida  e  operacional  das 
funções  implementadas  pela  solução  deste  trabalho,  resultando  em  uma  eficiência 
comprovada  da  ferramenta  na  realização  de  seus  papéis  básicos.  Apesar  disso,  houve 
identificação de algumas ressalvas. 

5.1.1. Problemas de SEO 


A  escolha  de  utilização  de iframes para composição dos micro frontends trouxe consigo 
uma dificuldade de indexação por sites de buscas como o Google. 

5.1.2. Problemas de segurança 


Mais  um  problema  causado  pela  escolha  do  mecanismo  de  composição.  Os  iframes  já 
foram  abordados  por  diversos  estudos  como  um  risco  de  vulnerabilidade  crítica  para 
projetos,  principalmente  quando  citado  sob  ataques  de  frame  hijacking  e  clickjacking. 
Porém,  os  navegadores  vêm  investindo  uma  grande  quantidade  de  recursos  que 
objetivam  sanar  essas  deficiências  com  o  tempo  e  um  exemplo disso é o surgimento no 
HTML  5  do  iframe  sandbox  (o  qual  foi  utilizado  neste  projeto),  navigation policies e o 
same origin policy (SOP) de forma a dificultar a existência desse tipo de risco [15]. 
É  importante  citar  que  testes  de  ataques  de  vulnerabilidade  de  segurança  não 
foram executados no projeto. Portanto, esse é apenas um item de sobreaviso.
 

5.2. Migração de sistemas legados 


A  segmentação  arquitetural  da  solução  em  diversos  módulos  provê  uma  possibilidade 
de utilização da ferramenta para a migração de sistemas legados em dois cenários: 
● Meio  para  modernização  de  tecnologia​,  exemplo:  migração  de  uma aplicação 
frontend de ASP.NET Web Forms para uma nova aplicação em React.js. 
● Meio  para  mudança  arquitetural​,  exemplo:  migração  de  uma  aplicação 
frontend  de  ASP.NET  Web  Forms  para  uma  nova  aplicação  com  arquitetura  de 
micro frontends e segmentando seu conteúdo por contextos de negócio. 

5.2.1. Meio para modernização de tecnologia 


Para  utilização  da  ferramenta  como  um  meio  para  a  modernização  de tecnologia de um 
projeto  legado  vê-se  necessário  a  instalação  e  configuração  do  módulo  mf-broker  no 
ambiente  final  de  utilização,  além  de  algumas  poucas  adições  de  código  JavaScript  na 
antiga aplicação. 
Imaginando  uma  aplicação  monolítica  legada  construida  em  ASP.NET  Web 
Forms que deseje segmentar e modernizar suas verticais de desenvolvimento (frontend e 
backend),  as  primeiras  tarefas  a  serem  executadas  para  a  migração  do  ​frontend  ​são 
relacionadas  a  criação  e  configuração  de  um  novo  projeto  que  utilize  uma  ferramenta 
moderna  de  construção  de  interfaces,  por  exemplo  React.js,  e  o  desenvolvimento  dos 
artefatos de reuso do sistema (header, menu e footer). 
Uma  vez  que  as  tarefas  iniciais  estejam  concluídas,  é  feita  a  instalação  da 
dependência  “@rollcakejs/rollcake-mf-broker”,  realizada  uma  importação  e  declaração 
da  classe “RollCakeMFBroker”, e em sequência segue-se com os passos exemplificados 
nas  tabelas  1  e  2  da  seção  4.1.  Contudo,  a  declaração  do  atributo  “address”  de  cada 
“bucket”  deverá  partir  de  um  endereçamento  de  página  específico  que  defina  uma 
segmentação de contexto de negócio da aplicação legado. 
 

 
Figura 19. Exemplo de segmentação por contexto de negócio e declaração de 
variáveis 
Realizada  a  declaração  e  segmentação  dos  contextos  de  negócio  de  cada  micro 
frontend,  o usuário deverá, para cada contexto de negócio identificado, criar uma página 
e  rota  com  as tecnologias de construção de UI providas pela ferramenta escolhida. Logo 
em  seguida,  deverá  ir  aos  arquivos  de  criação  e renderização de componentes e realizar 
a  declaração  de  um  elemento  com  a  tag  “rollcake-microfrontend”.  Essa  tag  deverá 
conter  um  atributo  “name”  preenchido  com  um  valor  idêntico  a  um  dos  segmento  de 
contexto  de  negócio  que  foram  declarados  no  parágrafo  anterior,  assim  como 
exemplificado na Tabela 3 da seção 4.1. 
Uma  vez  que  esteja  funcionando  a  exibição,  é  hora  de  remover  os  artefatos  de 
reuso  do  sistema  antigo,  afinal  já  foram  portados  para  a  nova  ferramenta,  e  utilizar  os 
serviços  da  interface  de comunicação e dos dados compartilháveis disponibilizados pela 
variável de janela “RollCake” exemplificados na Tabela 4 da seção 4.1. 
Ao  final,  o  usuário  terá  um  portal  em  React.js  suportando  um  ambiente 
temporário  com  a  arquitetura  de  micro  frontends  que  possibilita  a  escrita  de  novas 
funcionalidades  ou  reescrita  de  antigas,  e  a  coexistência  da  versão  legado  (pelo  menos 
enquanto a aplicação não for totalmente reescrita). 

5.2.2. Meio para mudança arquitetural 


Para  a  utilização  da  ferramenta  como  um  meio  de  mudança  arquitetura  de  um  projeto 
legado existem quatro possíveis cenários: 
 

● Utilização  do @rollcakejs/rollcake-spa como aplicação contêiner e considerando 
organização de repositório como mono-repositório; 
● Utilização  do @rollcakejs/rollcake-spa como aplicação contêiner e considerando 
organização de repositório como multi-repositórios; 
● Utilização  de  uma  biblioteca  de  construção  de  UI  qualquer  como  aplicação 
contêiner  auxiliado  pelo  @rollcakejs/rollcake-mf-broker  e  organização  de 
repositório como mono-repositório; 
● Utilização  de  uma  biblioteca  de  construção  de  UI  qualquer  como  aplicação 
contêiner  auxiliado  pelo  @rollcakejs/rollcake-mf-broker  e  organização  de 
repositório como multi-repositórios; 
Cada  abordagem  irá  variar  a  depender  das  necessidades  de  cada  projeto  de 
desenvolvimento.  Portanto,  para um cenário de exemplificação hipotético será abordado 
apenas  o  primeiro  caso  o  qual  deve  ser considerado o caminho mais curto para alcançar 
o objetivo desta seção. 
Em  um  ambiente  em  que  se  deseja  utilizar  o  @rollcakejs/rollcake-spa  como 
aplicação  contêiner  e  uma  arquitetura  de  repositório  organizado  como  um  todo 
(mono-repositório),  basta  utilizar  o  template  de  inicialização  de  projetos  localizado  no 
repositório ​rollcake-spa-template​. 
A  partir  da transferência e instalação de dependências do template anteriormente 
mencionado,  o  usuário  deverá  executar  o  desenvolvimento  dos  artefatos  de  reuso 
(header,  menu  e  footer) seguindo de exemplo a construção de componentes encontrados 
na Tabela 10 da seção 4.3. 
Uma  vez  que  os  componentes  estejam  prontos,  o  usuário  deverá  ir  ao  arquivo 
mf-broker.config.js  e  realizar  o  mesmo  passo-a-passo  da  seção  5.2.1,  a  qual  refere-se a 
declaração  e  segmentação  dos  contextos  de  negócio  de  cada  micro  frontend  da 
aplicação legado. 
Logo  em  seguida,  para  cada  contexto de negócio deverá ser criada uma página e 
para  cada  página  uma  nova  rota  no  arquivo  router.config.js.  Dentro  de  cada  página 
deverá  ser  realizada  a  declaração  de  um  elemento  de  micro  frontend.  A  criação  de 
páginas  pode  ser  vista  na  Tabela  9  da  seção  4.3 e a configuração de rota na Tabela 5 da 
seção 4.2. 
Assim  como  a  seção  5.2.1,  uma  vez  que  a  exibição  da  aplicação  legado  esteja 
funcionando,  remova  os  artefatos  de  reuso  do  sistema  antigo  e  utilize  os  serviços  da 
interface  de  comunicação  e  dos dados compartilháveis disponibilizados pela variável de 
janela “RollCake”. 
Ao  final,  o  usuário  terá  um  portal  de  SPA  construído  sob  utilização  do 
rollcake-spa  suportando  um  ambiente  com  a  arquitetura  de  micro  frontends  que 
disponibiliza  ao usuário a possibilidade de escrita de novas funcionalidades com suporte 
a  diferentes  tecnologias,  modernização  de  antigas  ferramentas  e  coexistência  com  a 
versão legado. 
 

5.3. Criação de sistemas do zero 


Para  criação  de  sistemas  do  zero  existem  os  mesmos  quatro  possíveis  cenários  de 
utilização da seção 5.2.2.  
Com  a  mesma  justificativa  de  agilidade  de  produção  da  seção  mencionada  será 
abordado  apenas  o  cenário  que  utiliza-se  do  template  de  inicialização  de  projetos  do 
rollcake-spa.  Felizmente,  este  trabalho  já  apresenta  durante  os  resultados  de 
desenvolvimento  um  passo  a passo bastante elaborado para a criação de uma solução do 
zero,  portanto,  basta  seguir  os  exemplos  de  configuração  e  integração  expostos  a  partir 
da seção 4.5 para os objetivos esperados serem alcançados. 

6. Conclusão e direções futuras 


Esse  trabalho  forneceu  o  desenvolvimento  de  uma  solução  para  abstração  do  processo 
de  integração  de  micro  frontends  que  pretendia  resolver  a  dificuldade  de  suporte  às 
tecnologias  legadas  e  os  demasiados  processos  de  configuração  apontados  no 
single-spa.  Os  resultados  mostraram  uma conclusão satisfatória com o desenvolvimento 
de  um  protótipo  de  interface  de  programação  de  aplicativos  (API)  em  JavaScript.  Foi 
possível  atingir  os  objetivos  esperados,  obtendo  um  produto  que  cumpre  os  papéis 
básicos  definidos  pela  arquitetura  em tema e que alcançou, a partir da utilização de uma 
técnica  de  composição  com  auxílio  de  iframes  e  uma  interface  de  compartilhamento 
auxiliada  por  variáveis  de  janela,  um  maior  suporte  às  tecnologias  de  frontend  e 
facilitação  do  processo  de  configuração  nos  projetos  dos  fragmentos.  Por  outro  lado, 
possui  pontos  de  ressalva  que  podem  tornar  sua  utilização  pouco  atrativa  em  um 
ambiente  de  desenvolvimento  real  que  deseje  realizar  uma  grande  estratégia  de 
marketing  digital  ou  que  tenha  um  alto  rigor  de  segurança,  sendo  mais  recomendado 
para  soluções  que  visem  construir  e  que  desejem  realizar  um  processo  de  migração  de 
uma aplicação legado. 
Dado  esse  contexto,  há  uma  oportunidade  para  estudos  e  melhorias  dessa 
ferramenta  em  trabalhos  futuros.  Mais  especificamente,  há  possibilidade  para  rever  o 
método  de  composição  dos  micro  frontends  (a),  refatorar  algoritmos  de  renderização 
(b),  investigar  ou  revisar  vulnerabilidades  nos  iframes  (c)  e,  até  mesmo,  estruturar uma 
solução que consiga ajudar sistemas de busca a entender o conteúdo de iframes (d). 

7. Referências bibliográficas 
[1] Caifang Yang et al. “Research and Application of micro frontends”. IOP Conference 
Series Materials Science and Engineering. 2019. 
[2] Dragoni, Nicola, et al. "Microservices: yesterday, today, and tomorrow." Present and 
ulterior software engineering. Springer, Cham. 2017. 
[3] KALSKE, Miika et al. Transforming monolithic architecture towards microservice 
architecture. 2018. 
[4] Pavlenko, Andrey, et al. "micro frontends: application of microservices to web 
front-ends." Journal of Internet Services and Information Security (JISIS). 2020. 
[5] Newman, S., Building microservices. O’Reilly Media, Inc., 2015. 
 

[6] Cam, Jackson. Micro Frontends. Outubro, 2020. Disponível em: 


<​https://martinfowler.com/articles/micro-frontends.html​>. 
[7] Canopy, single-spa. Acesso em: 27/10/20. Disponível em: 
<​https://single-spa.js.org/​>. 
[8] Bastos, João Pedro da Silva. Desenvolvimento Web Orientado a micro frontends. 
Diss. 2020. 
[9] Peltonen, Severi, Luca Mezzalira, and Davide Taibi. Motivations, Benefits, and 
Issues for Adopting micro frontends: A Multivocal Literature Review. 2020. 
[10] Luca Mezzalira, increment. micro frontends in context. Acesso em: 27/10/20. 
Disponível em: <​https://single-spa.js.org/​>. 
[11] Evan You, Vue.js. Acesso em: 08/09/20. Disponível em: <​https://vuejs.org/​>. 
[12] Google, Angular. Acesso em: 27/10/20. Disponível em: <https://angular.io/>.  
[13] Facebook Inc., React. Acesso em: 27/10/20. Disponível em: 
<​https://pt-br.reactjs.org/​>. 
[14] Svelte, Svelte. Acesso em: 27/10/20. Disponível em: <​https://svelte.dev/​>. 
[15] Stefano Calzavara, et al. A tale of two headers: a formal analysis of inconsistent 
click-jacking protection on the Web. USENIX Security. USENIX Association, 2020. 
[16] Sooel Son and Vitaly Shmatikov. The postman always rings twice: Attacking and 
defending postmessage in HTML5 websites. NDSS. The Internet Society, 2013. 
[17] Wang, Daojiang, et al. “A Novel Application of Educational Management 
Information System Based on Micro Frontends.” Procedia Computer Science, 2020. 
[18] Zhu, Bin Benjamin, et al. "Component-oriented architecture for web mashups." 
2015. 
[19] Kalske, Miika. "Transforming monolithic architecture towards microservice 
architecture." 2018. 
[20] Nascimento C. H. P., Eder C. S. S. "MICROFRONTEND: um estudo sobre o 
conceito e aplicação no frontend." Revista Interface Tecnológica, 2020. 
 
 
 
 
 
 
 
 
 
 

APÊNDICE A. SOLUÇÕES ELABORADAS E ELIMINADAS DURANTE O 


PROCESSO DE BRAINSTORMING 
Codinome  Descrição  Justificativa 

Criação de um módulo  1. Solução muito simples e 


responsável pelo de exibição  abrangente que não iria abstrair 
Frank 
tags iframes que representam  tanto o processo de construção 
os micro frontends.  como o desejado. 

Criação de um módulo 
responsável pela  1. Difícil manutenibilidade a longo 
Wrapper  renderização de elementos e  prazo, devido a estrutura 
micro frontends via iframe, e  monolítica. 
roteamento de página. 

Criação de um módulo 
responsável pela  1. Difícil manutenibilidade a longo 
renderização de elementos e  prazo, devido a estrutura 
micro frontends via web  monolítica; 
components extensíveis de  2. Arquitetura de componentização 
Atomic 
iframes, e roteamento de  (Atomic Design) não muito 
página. Porém, com uma  utilizado e conhecido pelos 
arquitetura de construção de  desenvolvedores frontend, assim 
elementos voltada para o  dificultando a aderência. 
Atomic Design. 

1. Solução muito simples e 


Criação de um módulo 
abrangente, assim não iria 
responsável pela inserção de 
abstrair tanto o processo como o 
micro frontends utilizando 
desejado; 
web components extensíveis 
Mimic  2. Tempo hábil para construção da 
de divs com lógica redefinida 
custom tag similar ao 
para apresentação de 
comportamento de um iframe 
comportamento similar aos 
com mesma facilidade de 
iframes. 
suporte. 

You might also like