Blog

30 de março de 2021

Monorepo + Yarn workspaces

Imagine instalar uma biblioteca para realizar chamadas http para uma api e configurar ela em vários projetos diferentes, um exemplo disso seria uma renovação de token jwt ou até mesmo uma autenticação de usuário, sem o monorepo, teríamos que manter essa lógica em uma pasta/repositório “utils” ou até mesmo manter o “velho” copia e cola sempre que criarmos um projeto novo trazendo dificuldades de manutenção e escala pela questão de duplicidade de código.

Por conseguinte, o monorepo não traz somente consistência e escala para nosso código, ele evita duplicidade, onde podemos criar “pacotes” com o que precisamos e compartilhar com os projetos dentro do repositório.

Um exemplo disso seria um projeto para organizar os estilos do nosso sistema como um Design tokens e/ou UI de componentes no qual esse “pacote” precisa de manutenção e refinamento para servir outros projetos que mantém a lógica da nossa aplicação.

Como nem tudo é perfeito o monorepo tem suas desvantagens, separei algumas que na minha opinião foram as que mais geraram aquela dúvida: “será que uso?”.

Infelizmente, você não pode compartilhar apenas a parte do seu monorepo que terá acesso a toda a base de código.

Como você terá muito código-fonte em um só lugar, levará muito mais tempo para que seu CI execute tudo a fim de aprovar cada PR.

Caso utilize ferramentas como Github actions, teamcity será necessário configurar para que alterações nos “pacotes” do projeto não gerem builds desnecessárias para “pacotes” não alterados.

Exemplo, ao realizar alteração no pacote pacoteX, o github actions executa todo serviço de CI do projeto caso você não especifique os path para actions.

Exemplo de configuração:

Agora que sabemos vantagens e desvantagens, vamos por a “mão na massa”. Como configurar um monorepo?

Primeiramente vamos criar uma pasta chamada meu-primeiro-monorepo e entrar nela para iniciarmos um projeto node com Yarn.

mkdir meu-primeiro-monorepo && cd meu-primeiro-monorepo && yarn init -y

depois disso será criado um arquivo package.json contendo o seguinte conteúdo:

Agora, para configurar nosso monorepo precisamos definir qual pasta será o nosso workspace.

Nesse momento você deve estar se perguntando, “O que é um workspace?”, um workspace seria um ambiente de trabalho configurado no projeto para compartilhar scripts, dependências, configurações e testes.

Você pode configurar quantos workspaces quiser, isso vai da necessidade do projeto.

No caso vou configura um workspace único com o nome packages:

package.json:

Agora é só criar a pasta “packages” e organizar os pacotes que você queira compartilhar dentro dela.

Por exemplo, vou criar um pacote A:


mkdir pacote-a && cd pacote-a && yarn init -y && cd ..


e outro B:


mkdir pacote-b && cd pacote-b && yarn init -y && cd ..


Na sequência renomear os pacotes para consumi-los.

Dentro do arquivo package.json no atributo name coloque o nome do pacote.

package.json pacote A:


{
"name": "@meu-primeiro-monorepo/pacote-a",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
}


package.json pacote B:


{
"name": "@meu-primeiro-monorepo/pacote-b",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@meu-primeiro-monorepo/pacote-a": "*"
}
}

Obs.: o nome @meu-primeiro-monorepo pode ser qualquer nome que quiser.

Agora é só executar yarn install na pasta raiz do nosso projeto.
Pronto!!

Agora abrindo a pasta node_modules verificamos que existe uma pasta @meu-primeiro-monorepo com um link simbólico para pasta real.

Para testes vamos criar um arquivo index.js em cada pacote com seguinte conteúdo:

pacote A:


module.exports = function helloWorld(){
console.log("Console.log a partir do pacote-a")
}


pacote B:

const pacoteA = require("@meu-primeiro-monorepo/pacote-a")
console.log("pacote-b")
pacoteA()


Agora é só executar node packages/pacote-b/index.js a partir da raiz do projeto.
Com essa estrutura você pode criar projetos escaláveis e consistentes.

Conclusão

Se você trabalha com microsserviços e/ou microfrontends, ou possui várias aplicações e pretende criar bibliotecas compartilhadas entre elas, o monorepo traz a proposta de liberdade de criar um novo projeto sem precisar criar repositórios e pedir para o time inteiro cloná-lo, além de trazer desempenho corporativo para toda a equipe de profissionais envolvidos com este trabalho que requer agilidade, habilidade e principalmente parceria na tomada de decisões.


Originally published at https://israel-sampaio.medium.com on March 30, 2021.