Transformando seu projeto Vue.js em Micro-frontends com Server Side Rendering

Maniero
6 min readSep 22, 2020

Há diversos benefícios em transformar sua aplicação Vue.js em micro-frontends. Com micro-frontends existe a possibilidade de substituir um legado em etapas, migrar de tecnologia, melhora reutilização de código entre produtos e habilitar diversos times a modificar o mesmo produto sem ter que mexer no mesmo codebase (bye bye merge hell!).

Se você está lendo esse artigo, provavelmente você já tem um codebase relativamente grande e esteja começando a pensar em fatiá-lo. Afinal, ninguém começa um projeto front-end do zero já com micro-frontends. Pelo menos não deveria.

Então, vamos ver como o Ragu ajuda nessa tarefa e como é possível, em apenas alguns passos transformar seu monolito em micro-frontends.

Criando um Projeto Vue.js

Vou criar um projeto usando vue-cli só para usarmos de exemplo.

$ yarn global add @vue/cli
$ vue create ragu-vue-test-app

Criei o projeto com tudo como padrão e…

🎉  Successfully created project ragu-vue-test-app.
👉 Get started with the following commands:
$ cd ragu-vue-test-app
$ yarn serve

Temos uma aplicação Vue.js Rodando na porta 8080! Uhuu.

Configurando o Ragu Server

Para expor seus componentes como micro-frontends é necessário uma instância do Ragu Server. O Ragu server será responsável em fazer o build do seus componentes e irá expor seus micro-frontends com renderização do lado do servidor (SSR).

$ yarn add ragu-server ragu-vue-server-adapter webpack-merge

Vamos adicionar os scripts do iniciar o ragu no package.json.

  • ragu:build gera o build de produção.
  • ragu:start iniciar o servidor de produção (necessário rodar ragu:build antes).
  • Já o comando ragu:dev inicia o servidor de desenvolvimento (não precisa rodar ragu:build antes) com hot-reload.
  "scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"ragu:build": "ragu-server build ragu-config.js",
"ragu:start": "ragu-server run ragu-config.js",
"ragu:dev": "ragu-server dev ragu-config.js"

},

Vamos criar nosso arquivo de configuração do ragu-server. Crie um arquivo chamado ragu-config.js com o seguinte conteúdo:

Externalizando um componente como micro-frontend

Sabe aquela tela de boas vindas bonitona do Vue.js? Ela vai ser o componente que vamos externalizar. Vamos criar uma pasta chamada ragu-components. Conforme definido em config.components.sourceRoot. E criar um arquivo chamado ragu-components/hello-world/index.js.

Será que está funcionando?

yarn ragu:dev

Para ter uma prévia do componente, basta acessar a URL http://localhost:3101/preview/o-nome-da-pasta-do-seu-componente. No nosso caso hello-world.

🌎 http://localhost:3101/preview/hello-world/

E conseguimos ver a mesma tela.

Consumindo o Micro-frontend

Ok, a gente consegue ver a mesma página em uma URL diferente. Mas como eu uso isso? Vamos criar uma página bem simples pra testar o nosso micro-frontend.

Como você pode observar. Para consumir o micro-frontend, você vai precisar basicamente de adicionar o ragu-dom na página, e adicionar o <ragu-component /> substituindo a /preview/ para /components/ da URL que estávamos acessando.

Agora você pode utilizar seu micro-frontend onde você quiser!

Recebendo Propriedades

Provavelmente, quando você montar um micro-frontend, deseja passar algumas propriedades que serão utilizadas para a renderização.

Vamos passar a receber o título do nosso micro-frontend de forma dinâmica.

Primeiro é necessário alterar o App.vue para receber o título.

Agora basta alterar nosso componente ragupara conseguir usar passar props dinâmicas para o componente. Arquivo ragu-components/hello-world/index.js:

🌎 http://localhost:3101/preview/hello-world/?title=My%20Title

Renderizando um estado dinâmico

Como eu disse anteriormente, o Ragu Server entrega componentes com SSR. Caso você precise de algum estado dinâmico para renderizar seu componente como, por exemplo, o resultado de uma request. Você pode implementar um estado para seu componente.

Basta criar um arquivo state.js na mesma pasta que seu componente. No caso ragu-components/hello-world/state.js.

A função propsToState recebe as propriedades do componente e mapeia elas para um estado. Essa função retorna uma Promise, sendo assim, é possível fazer uma request ou usar qualquer tipo de processamento assíncrono.

Nosso micro-frontend deixa de utilizar props para renderizar o componente Vue.js e utiliza o estado:

Agora não nos interessa mais as propriedades e utilizaremos o estado para renderizar o componente.

🌎 http://localhost:3101/preview/hello-world/?name=Maniero

Utilizando CDN

Você provavelmente vai querer exportar diversos micro-frontends. Se cada micro-frontend incluir o Vue.js em seus bundles você fará os seus usuários baixar diversas vezes a mesma biblioteca. Para evitar esse tipo de problema, você pode configurar o servidor do Ragu para utilizar o CDN do Vue.js e não incluir o Vue.js no bundle do micro-fronend.

Em defaultDependencies é possível passar uma lista de dependências.

  • nodeRequire representa a string é que passada para o require/import do node. No caso do vue import Vue from 'vue'.
  • dependency A URL da CDN de onde o Vue.js (ou qualquer outra dependencia) deve ser carregada.
  • globalVariable é o nome da variável global no browser onde aquela dependência é carregada. Se você estiver em uma página que tem a CDN do Vue.js e digitar Vue no console, você verá algo como o abaixo. Todos os imports serão substituídos para utilizar essa variável.

Vamos dar uma olhada no que é carregado antes e depois de declarar as dependências.

Antes e Depois:

MAS ANTES EU CARREGAVA 81.6KB agora estou carregando 103KB MAS QUE BELA OPTIMIZAÇÃO! 😡😡

O webpack por padrão elimina código não utilizado, então é natural que o arquivo da CDN seja um pouco mais pesado. Mas se você carregar mais um micro-frontend de mesmo peso com Vue você terá baixado 90.5+12.5 + 12.5 = 115.5kB. Caso não adicione a CDN 81.3 * 2 = 162.6kB. 😀

Essa é uma configuração que faz sentido quando você tem múltiplos micro-front-ends em Vue.

Repositório exemplo

O repositório com todos os exemplos acima você encontra em:

É isso! Agora você está pronto para usar micro-frontends com VueJS.

Outros links:

--

--