A demanda
- Criando um MonoRepo com Yarn Workspaces.
A primeira vez que utilizei Worskspaces do Yarn foi por conta do @ohager5, que criou o nosso projeto BVotal, no hackathon que participamos:
No bVotal havia 2 services e 2 fronts (um dashboard, um para o usuário).
Com o uso de workspaces, ficaram todos no mesmo repositório, e com um pouco de gitflow, trabalhamos ao mesmo tempo, e com muito mais agilidade do que se fosse necessário ficar pullando changes de cada proj o tempo todo, conforme novos commits iam sendo adicionados em cada service, ou front.
Foi uma forma legal de trabalharmos no mesmo repositório e também compartilhando as dependências.
Resultado:
- Exemplo deste post sobre Yarn Workspaces: no Github
Passo 1. Yarn
- Estou usando Node 18
Vamos garantir que estamos com a versão mais recente do yarn instalada.
Se não tiver yarn, instale:1
$ npm install --global yarn
Se tiver, atualize:1
2$ corepack enable
$ yarn set version stable
Passo 2. Criando o Workspace
Escolha uma pasta pro projeto.
Vamos criar como um workspace, onde teremos subprojetos que compartilham as dependências instaladas.
Também é interessante que tudo que precisamos para o projeto ficará no mesmo Repositorio GIT. POR EXEMPLO:1
2
3
4
5
6
7
8
9├── README.md
├── package.json
├── packages
| ├── Service1
| ├── Service2
| ├── AlgumaLib
| ├── Front01
| ├── Front02
└── yarn.lock
Inicie um novo projeto Yarn 2
terminal 1
$ yarn init -2
Edite o
package.json
para incluir a propriedadeworkspaces
. O meu ficou assim:package.json 1
2
3
4
5
6
7{
"name": "yarn-2-rcdevlabs-blog",
"packageManager": "yarn@3.2.2",
"workspaces": [
"packages/*"
]
}Basicamente estamos dizendo: “Olha, senhor Yarn…. Esse projetão tem vários wokspaces, e eles ficam na pasta packages.”
crie o diretório packages
terminal 1
2$ mkdir packages
$ touch packages/.gitkeep
Aqui podemos realizar o primeiro commit do projeto.
A partir de agora, criaremos nossas aplicações (services, bff, frontend) na pastapackages
(o .gitkeep foi adicionado apenas para seu commit ficar bonitinho)
1 | $ git add . |
Pode notar que não teremos pasta node_modules no projeto!
quick note sobre zero-installs
Atenção: Veja que a pasta .yarn tem uma pá de coisa e está sendo enviada ao GIT, mas tá tudo bem.
Isso é uma feature do Yarn PnP - Plug n Play - chamada “Zero-Install”.
A idéia é que dê pra rodar o projeto logo após clonar, sem precisar baixar as dependências. Ousado.
Pode notar que não teremos pasta node_modules no projeto!
Leia mais sobre o Zero-Installs Aqui
Passo 3: Crie novos componentes do seu projeto
- Como exemplo, vamos criar uma novo service usando NestJs
terminal 1
$ npx @nestjs/cli new packages/hello-service --skip-git
Lembrando de adicionar o --skip-git
, pois nosso repositório GIT já existe, e fica fora do BFF.
adicione a sessão scripts ao package.json, e vamos criar um atalho para rodar o modo desenvolvimento do NestJs.
package.json 1
2
3
4
5
6
7
8
9
10{
"name": "yarn-2-rcdevlabs-blog",
"packageManager": "yarn@3.2.2",
"scripts": {
"hsvc:dev": "yarn workspace hello-service start:dev"
},
"workspaces": [
"packages/*"
]
}Vamos ver se está rodando.
- Vamos mandar instalar as dependencias
- passando o parametro
workspace [name]
antes do comando.
- passando o parametro
- e depois rodar o script que criamos.
terminal 1
2$ yarn workspace hello-service install
$ yarn hsvc:dev
http://localhost:3000](http://localhost:3000)
conferir o “Hello Word” do NestJs.
O segundo commit traz o service1
2$ git add packages
$ git commit -m "feat(hello): new nestjs project as hello service package"
Ops
Para funcionar com o intelisense, precisamos instalar algumas dependencias no nosso projeto yarn. Os comandos abaixo instalam, como devDependencies, no projeto-raíz:terminal
1
2
3
4 $ yarn add -D typescript
$ yarn add -D prettier
$ yarn add -D ts-node
$ yarn dlx @yarnpkg/sdks vscode
Depois, vamos criar/editar uma configuração para o nosso Workspace1
2
3
4
5
6
7{
"typescript.tsdk": ".yarn/sdks/typescript/lib",
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
}
}
após essas alterações, reload a janela: ctrl/command shift p : reload window [enter].
Se pedir para instalar o plugin ZipFs, aceitar
Se algum arquivo estiver com erro nos imports, pode ser queo Vscode esteja interpretando o arquivo com a versão errada do TS. Ajuste assim:
vscode 1
2
3
4ctrl + shift + p
>TypeScript: Select TypeScript Version
--> escolha `Workspace Version`Uma vez que não haja mais erro, podemos commitar - mas só o que não estiver na pasta packages
terminal 1
2$ git add ':!packages' # adiciona tudo que não está na pasta packages
$ git commit -m "chore(yarn): add ts, prettier and ts-node"
Passo 4: Plug n Play Zero Install MESMO?
- Clone seu repositório em outra pasta, e rode diretamente (sem rodar install)
terminal 1
2$ yarn install
$ yarn hsvc:dev
Bom, a gente até rodou yarn install
, mas veja que nada foi baixado. Apenas a dependência @nestjs/core
foi buildada, a partir da própria .yarn/cache
.
E Vale a Pena?
Olha, pra comparar eu usei o npm install
no mesmo projeto, e olha só o tamanho da pasta node_modules
1 | $ du -hs node_modules/ |
Levando em conta que o projeto zero-installs
foi upado comprimido ao git com 70mb com todas as dependências, e apenas buildou o @nestjs/core localmente… O que vc achou?
Diz aí nos comentários.
Aviso: Considerações de segurança.
Conforme avisa o site do Yarn, se o projeto receber PRs de pessoas externas ao time, vale rodar um passo adicionar durante a Pipeline: $ yarn install --check-cache
. Com isso, yarn baixa novamente as dependências pra conferir o checksum, emitindo um alerta caso algo suspeito.
Conclusão
Bom, essa é a estrutura do MonoRepo usando Yarn Workspaces.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17├── README.md
├── package.json
├── packages
| ├── Service1
| ├── Service2
| ├── AlgumaLib
| ├── Front01
| ├── Front02
└── yarn.lock
# e mais os *dotfiles/folders*
└── .editorconfig
└── .gitignore
└── .pnp.cjs
└── .pnp.loader.mjs
└── .yarn
└── .yarnrc.yml
Utilizando a funcionalidade de workspaces do Yarn conseguimos ter todos os diferentes pacotes do nosso projeto unificados em um único repositório de projeto.
Existem algumas outras características ao trabalhar com workspaces, mas cobrí-las foge do objetivo desta série.
Outra feature bacaníssima do modo “Plug and Play” de pensar é a chamada Zero-Installs, onde nossas dependências são curadas e adicionadas ao GIT, não sendo necessario rodar Install após clonar o projeto.
Segundo Yarn, não ocupa muito espaço, pois são salvos apenas binários das dependências, e não todo o projeto, como quando usamos a boa e velha node_modules
.
Eventualmente pode ser necessário reinstalar uma dependência, com ou sem comittar ao GIT - por ex, se trabalhando em outro Sistema Operacional -, e há opções para isso.
Image by Freepik
Image by Freepik
Comments