Monorepositório com JavaScript: organização de código para iniciantes
Com o crescimento do projeto e o surgimento de lógica comum que precisa ser reutilizada em diferentes partes da aplicação, os desenvolvedores enfrentam o problema de organização do código. Muitos começam a copiar arquivos, criar pacotes npm separados ou módulos confusos. A solução para este problema é o monorepositório (monorepo). Neste artigo, vamos explicar o que é um monorepositório, por que ele é necessário no ecossistema JavaScript (Node.js) e como configurá-lo usando ferramentas populares. O artigo é voltado para desenvolvedores iniciantes que já conhecem os fundamentos do Node.js e npm.
O que é um monorepositório e por que ele é necessário?
Monorepositório é uma abordagem para organização de código onde todos os projetos, bibliotecas e serviços são armazenados em um único repositório (por exemplo, no GitHub). Ao contrário do multirrepositório (multirepo), onde cada projeto tem seu próprio repositório, o monorepositório une tudo em um só lugar.
Principais vantagens:
- Controle de versão unificado: Mais fácil gerenciar alterações que afetam vários pacotes.
- Reutilização de código: Utilitários, tipos e configurações comuns ficam próximos e não exigem publicação no npm.
- Simplificação de refatoração: Alterações em um pacote são automaticamente testadas junto com os outros.
- Build e testes unificados: É possível executar testes para todos os pacotes com um único comando.
No entanto, o monorepositório também tem desvantagens: pode se tornar muito grande, e o gerenciamento de dependências pode se tornar complexo. Para resolver esses problemas, existem ferramentas especiais.
Ferramentas para trabalhar com monorepositório em JavaScript
No ecossistema Node.js, existem várias ferramentas populares para gerenciar monorepositórios. Vamos abordar as duas mais comuns: NPM Workspaces (integrado ao npm) e Lerna.
NPM Workspaces
A partir da versão 7 do npm, foi adicionado suporte nativo para monorepositórios através de workspaces. Esta é uma forma simples e leve de organizar o código sem instalar pacotes adicionais.
Para configurar, basta criar um package.json raiz e especificar as pastas dos pacotes:
// package.json (raiz){ "name": "my-monorepo", "private": true, "workspaces": [ "packages/*" ]}Em seguida, crie a estrutura de pastas:
my-monorepo/├── package.json├── packages/│ ├── utils/│ │ ├── package.json│ │ └── index.js│ └── app/│ ├── package.json│ └── index.jsAgora, se o pacote app depende de utils, você pode simplesmente especificá-lo nas dependências:
// packages/app/package.json{ "name": "@my/app", "dependencies": { "@my/utils": "*" }}Após executar npm install na raiz do projeto, o npm criará links simbólicos entre os pacotes. Isso significa que você pode desenvolver ambos os pacotes simultaneamente, e as alterações em utils estarão imediatamente disponíveis em app.
Lerna
Lerna é uma ferramenta mais poderosa, frequentemente usada em conjunto com NPM Workspaces ou Yarn Workspaces. Ela adiciona funcionalidades para publicação de pacotes, versionamento e execução de comandos em todos os pacotes.
Instalação do Lerna:
npm install -g lernaCriação da configuração:
lerna initIsso criará um arquivo lerna.json e uma estrutura básica. Exemplo de configuração:
// lerna.json{ "version": "0.0.0", "packages": ["packages/*"], "npmClient": "npm"}Lerna permite executar comandos em todos os pacotes:
lerna run testlerna run buildE também gerenciar versões dos pacotes