Why NextWhy Next
Voltar à lista
💻 Dev3 min de leitura

5 apps num único repositório - o monorepo Turborepo de um dev solo

Como montar um monorepo Turborepo para gerenciar vários apps e sites num único repositório. Compartilhamento de configurações, economia de build com cache e deploy por app, tudo do ponto de vista prático.

Resumo

Quando você cria vários apps sozinho, as configurações se espalham. Com um monorepo Turborepo, eslint e tsconfig ficam compartilhados em packages, o cache do turbo evita rebuildar apps que não mudaram, e o --filter permite deploy por app.

Nesta página

Quando você cria apps sozinho, os repositórios se multiplicam sem parar. Um app, um site, mais um app... e lá está você copiando e colando a configuração do eslint pela quinta vez. Eu juntei tudo isso num único monorepo.

O problema de verdade são as configurações espalhadas

Com muitos repositórios, o que mais dói não é o código, são as configurações.

  • Copiar eslint, prettier e tsconfig para cada repositório
  • Mudar uma regra significa percorrer todos eles corrigindo
  • UI e utils compartilhados são pequenos demais para publicar no npm

O monorepo transforma isso em compartilhamento num único lugar.

Estrutura básica

apps/
├── web/      # 랜딩
├── blog/     # 이 블로그
├── wave/     # 오늘의 파도
└── ...
packages/
├── eslint-config/       # 공용 eslint
└── typescript-config/   # 공용 tsconfig

apps/* são os artefatos de deploy reais, e packages/* são as configurações e o código que os apps compartilham. O tsconfig.json de cada app só herda, assim:

{ "extends": "@repo/typescript-config/nextjs.json" }

Agora as regras são corrigidas num único lugar: packages.

O cache do turbo é o ponto-chave

A verdadeira arma do Turborepo é o cache. Se as entradas de uma tarefa (fontes e configurações) não mudaram, o resultado anterior é reutilizado como está.

turbo run build            # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog   # blog 앱만

Basta declarar as dependências entre tarefas e as saídas no turbo.json.

{
  "tasks": {
    "build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
  }
}

A partir do segundo build, ele termina em poucos segundos com "FULL TURBO".

Deploy por app

Mesmo num único repositório, o deploy fica separado por app. Com Docker, o turbo prune recorta apenas a subárvore daquele app, deixando a imagem leve.

turbo prune blog --docker   # blog + 내부 의존성만 남긴 out/ 생성

Este blog também foi recortado assim e subiu com Docker num mini PC. Essa história eu conto no post sobre self-hosting.

Resumo

  • apps/* = artefatos de deploy, packages/* = configurações compartilhadas
  • tsconfig e eslint gerenciados num único lugar via herança
  • O cache do turbo evita rebuildar apps que não mudaram
  • Deploy por app com --filter e prune

Se você toca vários produtos sozinho, o monorepo não é luxo, é ferramenta de sobrevivência.

Perguntas frequentes

A partir de quantos apps o monorepo compensa?

Já com mais de 2 apps, se surgem configurações compartilhadas (eslint, tsconfig, UI), compensa. O ponto central é corrigir a configuração num único lugar e refletir em todos os apps.

O build não fica mais lento?

Pelo contrário, fica mais rápido. O turbo faz cache do resultado das tarefas cujas entradas não mudaram e só rebuilda os apps que mudaram.

Artigos relacionados