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

\n\n

O desenvolvimento de projetos complexos em JavaScript (Node.js) frequentemente enfrenta o problema de gerenciamento de código. Quando você tem vários pacotes, bibliotecas ou microsserviços, cada um vivendo em seu próprio repositório, isso leva à duplicação de código, dificuldade de sincronização de versões e lentidão no CI/CD. A solução é o monorepositório (monorepo). Neste artigo, vamos analisar como organizar um monorepositório com JavaScript na prática: desde a escolha das ferramentas até a configuração da build e publicação.

\n\n

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

\n\n

Monorepositório é uma abordagem para gerenciamento de código onde todos os pacotes, bibliotecas e aplicações do projeto são armazenados em um único repositório. Ao contrário dos multirrepositórios (cada pacote em seu próprio repo), o monorepositório oferece:

\n\n
    \n
  • Histórico único de alterações: fácil rastrear como mudanças em uma parte afetam outra.
  • \n
  • Reutilização de código: utilitários e componentes comuns vivem em um só lugar sem necessidade de publicação no npm.
  • \n
  • Refatoração simplificada: a alteração da API de um pacote é imediatamente visível em todos os dependentes.
  • \n
  • Configurações unificadas de CI/CD: um único arquivo de configuração para todos os pacotes.
  • \n
\n\n

Para JavaScript (Node.js), o monorepositório é especialmente relevante, pois permite eliminar o "inferno das dependências" e acelerar o desenvolvimento. Vamos considerar a implementação prática.

\n\n

Ferramentas para monorepositório em JavaScript

\n\n

Existem várias ferramentas populares no mercado. Vamos considerar duas principais: npm workspaces (integrado ao npm) e Lerna (funcionalidade estendida).

\n\n

1. npm workspaces (suporte nativo)

\n\n

A partir do npm v7, o gerenciador de pacotes suporta workspaces. Esta é a maneira mais simples de começar. Exemplo de estrutura de projeto:

\n\n
my-monorepo/\n├── packages/\n│   ├── core/\n│   │   ├── package.json\n│   │   └── index.js\n│   ├── utils/\n│   │   ├── package.json\n│   │   └── helpers.js\n│   └── app/\n│       ├── package.json\n│       └── server.js\n├── package.json\n└── lerna.json (opcional)
\n\n

package.json raiz:

\n\n
{\n  "name": "my-monorepo",\n  "private": true,\n  "workspaces": ["packages/*"]\n}
\n\n

Agora todos os pacotes em packages/* são automaticamente vinculados. Para instalar as dependências, basta executar npm install na raiz. As dependências entre pacotes são especificadas de forma padrão:

\n\n
// packages/app/package.json\n{\n  "name": "@my/app",\n  "dependencies": {\n    "@my/core": "*",\n    "@my/utils": "*"\n  }\n}
\n\n

O npm workspaces cria symlinks na pasta node_modules, portanto, os imports funcionam como com pacotes comuns.

\n\n

2. Lerna (gerenciamento avançado)

\n\n

Lerna é uma ferramenta para gerenciar monorepositórios com capacidade de publicação, versionamento e execução de scripts em paralelo. Instalação:

\n\n
npm install --global lerna
\n\n

Inicialização no projeto:

\n\n
lerna init
\n\n

Arquivo lerna.json:

\n\n
{\n  "version": "independent",\n  "npmClient": "npm",\n  "packages": ["packages/*"]\n}
\n\n

O modo independent permite que cada pacote tenha sua própria versão. Comandos principais:

\n\n
    \n
  • lerna bootstrap — instala dependências e vincula pacotes.
  • \n
  • lerna run build — executa o script build em todos os pacotes.
  • \n
  • lerna publish — publica pacotes alterados no npm.
  • \n
\n\n

Organização prática do código

\n\n

Vamos considerar um exemplo de configuração de monorepositório para uma aplicação web com backend em Node.js e utilitários comuns.

\n\n

Passo 1: Estrutura básica

\n\n

Vamos criar três pacotes:

\n\n

Blogs

Book Recommendations