Monorepositório com JavaScript: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Monorepositório com JavaScript: organização de código na prática



No desenvolvimento web moderno com JavaScript (Node.js), surge cada vez mais a questão: como organizar o código de forma eficiente quando você tem vários pacotes, bibliotecas ou microsserviços que dependem uns dos outros? A abordagem tradicional com repositórios separados (multirepo) pode levar à duplicação de código, dificuldades com sincronização de versões e CI/CD lento. A solução é o monorepositório (monorepo). Neste artigo, vamos analisar o que é um monorepositório, por que ele é necessário e como organizá-lo na prática usando JavaScript.



O que é um monorepositório e por que ele é necessário?



Monorepositório é uma abordagem onde o código de vários projetos (pacotes, bibliotecas, serviços) é armazenado em um único repositório. Não se trata apenas de "colocar tudo em uma pasta", mas de uma arquitetura bem pensada que resolve muitos problemas:



  • Versão única de dependências: você evita situações onde diferentes pacotes usam versões diferentes da mesma biblioteca.
  • Refatoração facilitada: alterações em uma biblioteca compartilhada são imediatamente visíveis em todos os projetos que a utilizam.
  • CI/CD simplificado: um repositório — uma configuração de build e teste.
  • Compartilhamento de código: utilitários, tipos e configurações ficam disponíveis para todos os pacotes sem necessidade de publicação no npm.


No entanto, o monorepositório não é adequado para todos. Ele exige disciplina da equipe e boas ferramentas. Para JavaScript (Node.js), as principais ferramentas são npm workspaces (integrado ao npm 7+) e Lerna (uma ferramenta mais avançada).



Configuração de um monorepositório básico com npm workspaces



Vamos começar com um exemplo simples. Suponha que temos um projeto composto por dois pacotes: @myapp/core (núcleo com lógica de negócios) e @myapp/server (servidor em Express).



Vamos criar a estrutura de pastas:



my-monorepo/├── packages/│   ├── core/│   │   ├── src/│   │   │   └── index.js│   │   ├── package.json│   │   └── ...│   └── server/│       ├── src/│       │   └── index.js│       ├── package.json│       └── ...├── package.json└── ...


O package.json raiz deve conter o campo workspaces:



{  "name": "my-monorepo",  "private": true,  "workspaces": [    "packages/*"  ],  "scripts": {    "start": "node packages/server/src/index.js",    "test": "npm run test --workspaces"  }}


Agora, no packages/core/package.json:



{  "name": "@myapp/core",  "version": "1.0.0",  "main": "src/index.js"}


E no packages/server/package.json, adicionamos a dependência do core:



{  "name": "@myapp/server",  "version": "1.0.0",  "dependencies": {    "@myapp/core": "*",    "express": "^4.18.0"  }}


Após executar npm install na raiz, o npm criará symlinks entre os pacotes. Agora, no código do servidor, podemos importar o core diretamente:



// packages/server/src/index.jsconst express = require('express');const { calculate } = require('@myapp/core');

const app = express();app.get('/', (req, res) => { res.send(calculate(2, 3));});app.listen(3000);


Este é um exemplo básico, mas já mostra a principal vantagem: alterações no @myapp/core são imediatamente visíveis no @myapp/server sem necessidade de publicação em um registro.



Organização avançada com Lerna



Quando o número de pacotes ultrapassa 5-10, o npm workspaces pode não ser suficiente. É aí que entra o Lerna — uma ferramenta que adiciona recursos poderosos:



  • Execução de comandos em todos ou em pacotes selecionados.
  • Gerenciamento automático de versões (modo fixed ou independent).
  • Pu

Blogs

Book Recommendations