Monorepos com pnpm Workspaces e Turborepo: Guia de Organização
A Armadilha dos Múltiplos Repositórios: Como os Polyrepos Abrandam a Tua Equipa
À medida que o teu projeto digital cresce para lá de uma simples página web—integrando a plataforma dos clientes, uma área de administração, uma biblioteca de botões e formulários em comum e serviços backend em Node.js—a tua equipa depara-se com uma encruzilhada arquitetural:
Devemos criar repositórios Git separados para cada projeto (Polyrepo), ou juntar tudo dentro de um único repositório unificado (Monorepo)?
Ao início, ter vários repositórios parece organizado: crias empresa/portal-web, empresa/painel-admin e empresa/ui-componentes.
No entanto, passado poucos meses, este modelo transforma-se num labirinto doloroso de manutenção:
- O Funil dos Componentes Partilhados: Um colega altera um botão em
ui-componentes. Para usar esse botão noportal-web, tem de fazer commit, esperar que a pipeline compile o pacote, publicá-lo num gestor interno de npm na versão1.4.2, mudar de pasta para o outro repositório, atualizar opackage.jsone corrernpm install. - Divergência de Versões: O painel de administração fica preso na versão
1.2.0, enquanto o portal público usa a1.4.2. O design da marca começa a divergir em cada ecrã. - Pesadelo de Pull Requests Sincronizados: Mudar o nome de um campo na base de dados exige três Pull Requests abertos ao mesmo tempo em repositórios diferentes, impossibilitando testes integrados e rollbacks atómicos.
A COMPLEXIDADE DA GESTÃO COM MÚLTIPLOS REPOSITÓRIOS
-
- Atualizas o Botão → Commit → Publicas no npm (@empresa/ui v1.4.2)
- Portal Web: Atualiza dependência 3. Painel Admin: Esquecido! (Passa a usar a versão v1.4.2) (Fica na v1.2.0 com erros visuais!)
Para simplificares a tua engenharia de software segundo a visão de anti-over-engineering, a solução ideal passa por unificar os projetos com pnpm Workspaces e o motor de tarefas Turborepo.
A Eficiência do pnpm: Como os Hard Links Acabam com o Desperdício de Disco
Muitos programadores tinham receio de monorepos porque o npm e o Yarn criavam pastas node_modules com gigabytes de peso, duplicando ficheiros em cada subpasta e esgotando o espaço em disco.
O pnpm resolve este problema ao nível do sistema de ficheiros do Linux e Windows. Em vez de duplicar pacotes pesados como o React ou o TypeScript, o pnpm mantém um Armazenamento Global Indexado na máquina. Quando um projeto precisa de um pacote, o pnpm cria um hard link direto para esse bloco:
ARMAZENAMENTO COM HARD LINKS NO PNPM
- Armazenamento Central: ~/.local/share/pnpm/store/v3/…
- (Ligação Hard Link) — (Ligação Hard Link)
- /apps/web/node_modules (Zero espaço duplicado)
- /apps/admin/node_modules (Zero espaço duplicado)
Além disso, o pnpm elimina as chamadas dependências fantasma (phantom dependencies). Graças a symlinks isolados, o teu código só consegue importar bibliotecas que estejam explicitamente declaradas no teu próprio package.json.
Estrutura Profissional de um Monorepo com pnpm Workspaces
Vê como podes desenhar uma estrutura limpa e escalável para os teus projetos em TypeScript:
meu-projeto/apps/web/— Portal de Clientes (Astro ou Next.js)admin/— Painel Administrativo Internoapi/— API Backend em Fastify ou Express
packages/ui/— Biblioteca de Componentes com Tailwindbase-dados/— Modelos de Base de Dados e Migraçõesconfig-ts/— Ficheiros tsconfig.json partilhadosconfig-eslint/— Regras de código unificadas
pnpm-workspace.yamlturbo.jsonpackage.json
Na raiz do repositório, crias o ficheiro pnpm-workspace.yaml que indica onde estão os teus módulos:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
Dentro de apps/web/package.json, associas as bibliotecas locais com o protocolo dinâmico workspace:*:
{
"name": "web",
"version": "1.0.0",
"private": true,
"dependencies": {
"@empresa/ui": "workspace:*",
"@empresa/base-dados": "workspace:*"
}
}
Se alterares um botão em packages/ui, o teu portal em apps/web atualiza-se de imediato no browser sem precisares de compilar pacotes nem publicar versões de testes. É esta agilidade que usamos para construir web apps e websites estáticos rápidos.
Acelerar Tarefas com Turborepo: Grafos de Execução e Cache
Se o pnpm faz a ligação de pastas, o Turborepo gere a ordem de compilação, testes e formatação de código.
Tentar compilar múltiplos pacotes com scripts manuais gera conflitos e esperas desnecessárias. O Turborepo constrói um Grafo Acíclico Dirigido (DAG) para saber o que depende de quê.
Configuras o ficheiro turbo.json na raiz:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".astro/**", ".next/**"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.ts", "test/**/*.ts"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}
A instrução "dependsOn": ["^build"] garante que a biblioteca packages/ui compila antes de o apps/web tentar criar o bundle final.
GRAFO DE EXECUÇÃO DE TAREFAS NO TURBOREPO
- config-ts config-eslint
- packages/ui packages/base-dados
- (Execução Paralela)
- apps/web | apps/admin | apps/api
E o melhor de tudo é a cache inteligente. Se alterares apenas uma linha no apps/web, o Turborepo sabe que o apps/admin e a apps/api não foram mexidos. Quando a tua pipeline corre o turbo run build, recebes uma resposta imediata:
apps/admin:build: cache hit, ficheiros recuperados da cache (0.05s)
apps/api:build: cache hit, ficheiros recuperados da cache (0.04s)
apps/web:build: a compilar... (10.2s)
O tempo de publicação desce de quinze minutos para meros segundos, facilitando a criação de imagens limpas com o Docker.
Boas Práticas Operacionais: Isolamento de Contentores e Propriedade de Código
Seguindo as normas de engenharia adotadas na WebXtek, deves aplicar estas recomendações essenciais:
- Usa o Comando turbo prune nos Deploys: Quando fores criar a imagem Docker para a tua API, não queres copiar o repositório inteiro de 2GB. O comando
turbo prune --scope=api --dockerextrai apenas os pacotes e ficheiros necessários para essa aplicação específica. - Gere Versões com Changesets: Em vez de mudares versões à mão em dezenas de ficheiros
package.json, instala a ferramenta@changesets/clipara automatizares as alterações de versão sem falhas humanas. - Define Responsabilidades com o CODEOWNERS: À medida que a equipa cresce, define quem revê cada pasta no ficheiro
.github/CODEOWNERS:/apps/web/ @equipa-frontend /apps/api/ @equipa-backend /packages/base-dados @arquitetos-dados
Podes explorar mais modelos e estruturas de código aberto no GitHub. Ao juntares o pnpm workspaces com o Turborepo, eliminas a fricção entre projetos, manténs os teus contratos de código sempre alinhados e aceleras as publicações da tua equipa ao máximo.
Na prática, aplicas exatamente estes padrões operacionais em setores exigentes como saas empresarial b2b e especialistas em devops e arquitetura cloud. Quando alinhas a tua estrutura através de web apps e websites estáticos rápidos, transformas boas práticas técnicas numa vantagem competitiva real e mensurável para o teu negócio.
[+] [ INDEX_DIRECTORY ] 13 tópicos ▼
- A Armadilha dos Múltiplos Repositórios: Como os Polyrepos Abrandam a Tua Equipa
- A Eficiência do pnpm: Como os Hard Links Acabam com o Desperdício de Disco
- Estrutura Profissional de um Monorepo com pnpm Workspaces
- Acelerar Tarefas com Turborepo: Grafos de Execução e Cache
- Boas Práticas Operacionais: Isolamento de Contentores e Propriedade de Código
- Autor
- Perguntas Frequentes
- Qual é a principal vantagem de um monorepo face a múltiplos repositórios Git (polyrepo)?
- Como é que o pnpm workspaces elimina o desperdício de espaço no disco?
- O que acrescenta o Turborepo a uma infraestrutura com pnpm workspaces?
- Quando é que uma equipa deve evitar adotar um monorepo?
- Nós Relacionados
- Sequência do Caminho
Perguntas Frequentes
Qual é a principal vantagem de um monorepo face a múltiplos repositórios Git (polyrepo)?
Um monorepo junta várias aplicações e bibliotecas comuns dentro do mesmo repositório com controlo de versões. Permite commits atómicos entre pacotes, elimina divergências de versões em modelos de TypeScript e acelera alterações partilhadas sem teres de publicar pacotes intermédios.
Como é que o pnpm workspaces elimina o desperdício de espaço no disco?
O pnpm guarda todas as versões de pacotes num único armazenamento global no disco através de hard links. Além disso, a sua estrutura em árvore impede dependências fantasma, garantindo que o teu código só acede a pacotes explicitamente registados no seu package.json.
O que acrescenta o Turborepo a uma infraestrutura com pnpm workspaces?
O Turborepo organiza a compilação e os testes construindo um grafo de dependências (DAG). Compila em paralelo usando todos os núcleos do processador e guarda o resultado em cache local ou remota, para que tarefas inalteradas nunca voltem a ser compiladas.
Quando é que uma equipa deve evitar adotar um monorepo?
Um monorepo pode ser desvantajoso se os teus projetos forem totalmente independentes entre si, exigirem permissões de acesso muito restritas por equipa ou se a infraestrutura de CI/CD não tiver ferramentas de cache como o Turborepo para filtrar o que deve ser compilado.
[ RELATED_NODES ]
> INICIAR_PROJETO
Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.