
Nos últimos anos, o conceito de 
mono-repositórios se estabeleceu com sucesso, pois pode simplificar significativamente o processo de desenvolvimento de projetos de software modulares, como infraestruturas baseadas em microsserviços. As principais vantagens dessa abordagem arquitetônica são óbvias na prática; portanto, proponho criar seu próprio 
repositório de teste 
a partir do zero, entendendo simultaneamente as nuances de trabalhar com 
áreas de trabalho de fios e 
lerna . Bem, vamos começar!
Considere a estrutura do nosso projeto, que será três bibliotecas localizadas na pasta 
packages / , bem como 
package.json no diretório raiz.
├── package.json └── packages ├── app │  ├── index.js │  └── package.json ├── first │  ├── index.js │  └── package.json └── second ├── index.js └── package.json 
Entende-se que temos duas bibliotecas independentes 
primeiro e 
segundo , além de uma biblioteca de 
aplicativos que importará funções das duas primeiras. Por conveniência, todos os três pacotes são colocados no diretório 
packages . Você pode deixá-los na pasta raiz ou colocá-los em um diretório com qualquer outro nome, mas, para seguir as convenções geralmente aceitas, as colocaremos dessa maneira.
As bibliotecas 
primeiro e 
segundo por simplicidade do experimento conterão apenas uma função no 
index.js , cada uma das quais retornará uma sequência de hello em nome do módulo. Para o 
primeiro exemplo, ficará assim:
 
No módulo do 
aplicativo , exibiremos a mensagem 
Oi do aplicativo no console, além de cumprimentos de dois outros pacotes:
 
Para que o 
primeiro e o 
segundo estejam disponíveis no 
aplicativo , os denotamos como dependências nas 
dependências .
Além disso, para cada biblioteca, adicionamos o prefixo 
@ monorepo / no 
nome do valor na frente do nome principal do pacote ao 
package.json local.
 
Por que preciso de um prefixo com um ícone de cachorro na frente do nome do pacote npm (@ monorepo /)?A adição de um prefixo é opcional, mas esse 
é exatamente o 
tipo de convenção de nomenclatura 
de pacotes a que muitos monorepositórios aderem: 
babel ,
interface do usuário material , 
angular e outros. O fato é que cada usuário ou organização tem seu próprio 
escopo no site 
npm , portanto, há uma garantia de que todos os módulos com o 
@ somescope / postfix são criados pela equipe do 
somescope e não pelos atacantes. Além disso, torna-se possível chamar nomes de módulos que já foram utilizados. Por exemplo, você não pode simplesmente criar e criar seu próprio módulo de 
utilitários , porque essa biblioteca 
já existe . No entanto, adicionando o postfix 
@ myscopename / , podemos obter nossos utils ( 
@ myscopename / utils ) com blackjack e jovens senhoras.
 Um análogo da vida real para o nosso projeto de teste pode ser várias bibliotecas para trabalhar com dados, ferramentas de validação, análise ou apenas um conjunto de componentes da interface do usuário. Se assumirmos que vamos desenvolver um aplicativo 
Web e 
móvel (por exemplo, usando 
React e 
React Native, respectivamente), e tivermos parte da lógica reutilizada, pode valer a pena colocá-lo em componentes separados, para uso posterior em outros projetos. Adicione a isso o servidor no 
Node.js e você terá um caso muito real da vida.
Áreas de trabalho de fios
O toque final antes de criar um 
repositório mono completo será o design do 
package.json na raiz do nosso repositório. Preste atenção à propriedade de 
áreas de trabalho - especificamos o valor de 
packages / * , que significa "todas as subchaves na pasta 
packages ". No nosso caso, este é um 
aplicativo , 
primeiro , 
segundo .
 
Além disso, 
“private”: true deve ser especificado em 
package.json , pois os 
espaços de trabalho estão disponíveis apenas em projetos privados.
Para que tudo decole, execute o comando 
yarn (análogo ao 
yarn install ou 
npm install ) no diretório raiz. Como as dependências existentes no módulo de 
aplicativo são definidas como 
áreas de trabalho no 
pacote raiz.json , na verdade, não faremos download de nada do 
npm-registry , mas simplesmente vincularemos ("vincularemos") nossos pacotes.
 yarn 

Agora podemos executar o comando do 
nó. no diretório raiz que executará o script no 
arquivo packages / app / index.js .
 node . 

Vamos ver como isso funciona. 
Ao chamar 
yarn , criamos links simbólicos em 
node_modules para nossos diretórios na pasta 
packages .

Devido a esse relacionamento nas dependências, tivemos uma grande vantagem - agora, ao mudar no 
primeiro e no 
segundo módulos, nosso 
aplicativo receberá a versão atual desses pacotes sem reconstruir. Na prática, é muito conveniente, porque podemos conduzir o desenvolvimento local de pacotes, ainda os definindo como dependências de terceiros (que acabam se tornando).
A próxima vantagem importante que você pode obter ao trabalhar com 
áreas de trabalho de fios é a organização do armazenamento de dependências de terceiros.
Saiba mais sobre o armazenamento de dependências no nível superior.Suponha que 
desejássemos usar a biblioteca 
lodash no 
primeiro e no 
segundo . 
Ao executar o comando yarn add lodash a partir dos diretórios apropriados, receberemos uma atualização para o 
package.json local - a versão atual do pacote aparecerá em 
dependências .
 "dependencies": { "lodash": "^4.17.11" } 
Quanto ao 
próprio pacote 
lodash - fisicamente, a biblioteca será instalada no 
node_modules no nível raiz uma vez.
Se a versão exigida do pacote externo (no nosso caso, 
lodash ) for diferente para o 
primeiro e o segundo (por exemplo, 
primeiro você precisará do 
lodash v3.0.0 e no 
segundo v4.0.0 ), um pacote com uma versão inferior ( 
3.0.0 ) chegará ao 
nó node_modules raiz , e a versão 
lodash para o 
segundo módulo será armazenada em 
pacotes locais 
/ second / node_modules .
Além das vantagens, essa abordagem pode ter pequenas desvantagens, que o 
fio permite ignorar com a ajuda de sinalizadores adicionais. Você pode ler mais sobre essas nuances na 
documentação oficial .
 Adicionar Lerna
O primeiro passo para trabalhar com o 
lerna é instalar o pacote. Geralmente eles executam uma instalação global ( 
yarn global add lerna ou 
npm i -g lerna ), mas se você não tiver certeza se deseja usar esta biblioteca, poderá usar a chamada usando 
npx .
Inicializaremos o 
lerna a partir do diretório raiz:
 lerna init 

De fato, realizamos várias ações ao mesmo tempo com a ajuda de um comando: criamos um repositório git (se não tivesse sido inicializado antes disso), criamos um arquivo 
lerna.json e atualizamos nosso 
pacote raiz.json .
Agora, no recém-criado arquivo 
lerna.json, adicione duas linhas - 
“npmClient”: “yarn” e 
“useWorkspaces”: true . A última linha diz que já usamos 
áreas de trabalho de fios e não há necessidade de criar a 
pasta app / node_modules com links simbólicos para o 
primeiro e o 
segundo .
 
Testes com Lerna
Para mostrar a conveniência de trabalhar com o 
lerna, adicione testes para nossas bibliotecas.
No diretório raiz, instalamos o pacote para testing - 
jest . Execute o comando:
 yarn add -DW jest 
Por que preciso do sinalizador -DW?O sinalizador -D (- dev) é necessário para que o pacote jest seja instalado como uma dependência do desenvolvedor, e o sinalizador -W (- ignore-workspace-root-check) permite a instalação no nível raiz (o que precisamos).
 O próximo passo é adicionar um arquivo de teste ao nosso pacote. Para a conveniência do nosso exemplo, faremos todos os testes semelhantes. Para o 
primeiro exemplo, o arquivo de teste terá a seguinte aparência:
 
Também precisamos adicionar um script para executar testes no 
package.json de cada uma de nossas bibliotecas:
 
O toque final será atualizar o 
pacote root.json . Adicione um script de 
teste que chamará 
lerna run test --stream . O parâmetro após 
lerna run define o comando que será chamado em cada um de nossos pacotes a partir da pasta 
packages / , e o sinalizador 
--stream nos permitirá ver a saída dos resultados no terminal.
Como resultado, o 
package.json do diretório raiz ficará assim:
 
Agora, para executar os testes, precisamos apenas executar o comando a partir da raiz do nosso projeto:
 yarn test 

Atualização de versão com Lerna
A próxima tarefa popular, com a qual o 
lerna pode lidar com a qualidade, será atualizar as versões dos pacotes. Imagine que, após a implementação dos testes, decidimos atualizar nossas bibliotecas da 1.0.0 para a 2.0.0. Para fazer isso, basta adicionar a linha 
“update: version”: “lerna version --no-push” ao campo de 
scripts do root 
package.json e, em seguida, execute 
yarn update: version no diretório raiz. O sinalizador 
--no-push é adicionado para que, após a atualização da versão, as alterações não sejam enviadas para o repositório remoto, o que o 
lerna faz por padrão (sem esse sinalizador).
Como resultado, nosso root 
package.json ficará assim:
 
Execute o script de atualização da versão:
 yarn update:version 
Em seguida, seremos solicitados a selecionar a versão para a qual queremos mudar:

Ao clicar em 
Enter , obtemos uma lista de pacotes nos quais a versão é atualizada.

Confirmamos a atualização digitando 
y e recebemos uma mensagem sobre a atualização bem-sucedida.

Se tentarmos executar o comando 
git status , não receberemos a mensagem 
para confirmar, trabalhando em uma árvore limpa , porque 
A versão lerna não apenas atualiza as versões dos pacotes, mas também cria um commit e uma tag git indicando a nova versão (v2.0.0 no nosso caso).
Recursos de trabalho com a equipe da versão lernaSe você adicionar a linha 
"version": "lerna version --no-push" em vez de 
"update: version": "lerna version --no-push" no campo de 
scripts do root 
package.json , é possível que encontre comportamentos inesperados e console vermelho. O fato é que o 
npm-scripts chama o comando 
version (script reservado) imediatamente após atualizar a versão do pacote, o que leva a uma chamada recursiva para a 
versão lerna . Para evitar essa situação, basta atribuir um nome diferente ao script, por exemplo, 
update: version , como foi feito em nosso exemplo.
 Conclusão
Esses exemplos mostram um centésimo de todas as possibilidades que a 
lerna possui em conjunto com os 
espaços de trabalho de fios . Infelizmente, até agora não encontrei instruções detalhadas para trabalhar com monorepositórios em russo, para que possamos assumir que o começo foi feito!
Link para o repositório do projeto de teste.