Monorepo - Single Repository, many modules
Published: 2020-06-29 20:29:36

![image](https://user-images.githubusercontent.com/12778450/79612389-fa5b5b00-80d2-11ea-9090-e9de262e869e.png)

## Part 1 - Monorepos, porquê dessa abordagem?

### What and Why?

Um monorepo é um conceito de arquitetura, que basicamente é o que diz.

Em vez de gerenciar vários repositórios, você mantém todas as suas partes de código isoladas dentro de um repositório.

Monorepo não tem nada em comum com monolíticos.

Você pode manter Vários tipos de aplicativos lógicos em um repositório; por exemplo, um site e seu aplicativo para iOS.

Este conceito é relativamente antigo e apareceu cerca de uma década atrás.

Você pode perguntar, se ele existe há uma década, então por que esse assunto é tão popular agora? 

Principalmente, ao longo dos últimos 5-6 anos, muitas coisas sofreram mudanças. ES6, pré-processadores SCSS, gerenciadores de tarefas, npm etc.

atualmente, para manter um pequeno aplicativo baseado no React, você precisa lidar com vários pacotes, suítes de testes, scripts de CI/CD, configurações do Docker sei lá o que mais.

Imagine que você precise manter várias apps.

Cada pacote precisará ter sua própria configuração de ambiente, significa que toda vez que você desejar criar um novo pacote, precisará tudo de novo, copiar todos os arquivos e assim por diante.

Outro exemplo, é se você precisar alterar algo build da aplicação por exemplo, vai precisar olhar cada repositório, fazer a correção, abrir um PR em todos eles, aguardar build em cada projeto, ver se deu certo.. 

Granularidade de configuracoes

Enfim, o torna muito lento. Nessas situacoes, faz sentido usar monorepo.

Em vez de ter muitos repositórios com suas próprias configurações, imagine ter uma fonte de verdade - o monorepo:

- suite de testes
- Centralizar configurações como eslint, CI/CD
- Arquivo de configuração Docker
- Configurações Webpack
- Pacotes semelhantes em cada aplicativo
- Executando comandos semelhantes
- bibliotecas com componentes e vários pacotes

Não é um mundo de flores.

### Vantagens

- **Um local para armazenar todas as configurações e testes.**

    você pode configurar seu CI / CD e bundler uma vez. O mesmo vale para testes de unidade, e2e e integração - seu CI poderá iniciar todos os testes sem precisar lidar com configurações adicionais.

- **Refatorar facilmente recursos globais.**

    Em vez de abrir um PR em cada repositório, ver qual ordem de alteração, abre em um só lugar.

- **Publicação de pacotes simplificada.**

    Se você pretende criar um lib de components e publicar isso em um registry. e os comandos são os mesmo pra isso, vale a pena usar monorepo

- **Gerenciamento de dependência mais fácil.** *package.json*

    Apenas um. Não é necessário reinstalar dependências em cada repositório sempre que você desejar atualizar suas dependências.

- **Reutilize o código com pacotes compartilhados, mas ainda sim isolados.**

    O Monorepo permite que você reutilize seus pacotes de outros pacotes, mantendo-os isolados um do outro. 

### Desvantagens

- Não há como restringir o acesso apenas a algumas partes do aplicativo
- Baixo desempenho do Git ao trabalhar em projetos de grande escala
- Maior tempo de construção e configuração. Quanto mais coisas ter que configurar, build, eslint, tests...

### Exemplos (Github)

- babel - [https://github.com/babel/babel](https://github.com/babel/babel)
- Facebook CRA - [https://github.com/facebook/create-react-app](https://github.com/facebook/create-react-app)
- jest - [https://github.com/facebook/jest](https://github.com/facebook/jest)
- Gatsby - [https://github.com/gatsbyjs/gatsby](https://github.com/gatsbyjs/gatsby)
- nextjs - [https://github.com/zeit/next.js/](https://github.com/zeit/next.js/)
- UAI - [https://github.com/belezanaweb/uai](https://github.com/belezanaweb/uai)

## Part 2 - Lerna

### Introduction

A tool for managing JavaScript projects with multiple packages.

Realmente ajuda a lidar com versões, a configurar o workflow de pacotes, publicação pro npm ou github, etc. A principal ideia do Lerna é que o projeto tenha uma pasta packages, que contém todas as partes de código isoladas.

Quase todos os comandos do lerna funcionam assim: O comando é repetido para todos os pacotes, como se entrasse em cada pasta. Por exemplo, bump de versão, limpar projeto, instalar dependencias, build...

### Using Lerna

Installing

    npm install -g lerna // yarn global add lerna

Init

    lerna init // --independent or -i 
    
    ls -l
    
    -rw-r--r--  1 user  staff    288B Mar 16 12:06 .git
    -rw-r--r--  1 user  staff    63B Mar 16 12:04 lerna.json
    -rw-r--r--  1 user  staff    91B Mar 16 12:04 package.json
    drwxr-xr-x  2 user  staff    64B Mar 16 12:04 packages

lerna.json

    {
      "packages": [
        "packages/*"
      ],
      "version": "0.0.0"
    }

Create package

    lerna create my-package
    
    lerna create my-module

Bootstrap

    lerna bootstap // will create links :)

Exec

    lerna exec -- ls // --scope or --ignore --

Clean

    lerna clean // delete node_modules

Publish

    lerna publish // for ci use --yes // npm publish and git tag

### Independent versioning

    {
      "packages": [
        "packages/*"
      ],
    	"version": "independent",
    }

### Show me the code

🚀

### Links

[https://blog.npmjs.org/post/186494959890/monorepos-and-npm](https://blog.npmjs.org/post/186494959890/monorepos-and-npm)

[https://medium.com/@chris_14660/learnin-lerna-for-monorepos-in-node-js-5b577bdbf380](https://medium.com/@chris_14660/learnin-lerna-for-monorepos-in-node-js-5b577bdbf380)