Capítulo 27 de 35

Turborepo na Vercel: A Engenharia por trás dos Monorepos Corporativos

Índice do Manual

Conforme uma startup evolui para uma corporação estabelecida, a complexidade do software se multiplica. O que antes era apenas "um site", rapidamente se transforma em três sistemas distintos:

  1. O Site Institucional (Marketing).
  2. O Painel Administrativo (Operação Interna).
  3. O Aplicativo SaaS (Onde o cliente paga).

O erro fatal de muitas equipes de TI é criar três repositórios de código isolados para esses projetos. O resultado? O botão principal de "Ação" precisa ser programado três vezes. A regra de negócio que calcula o desconto do cliente é copiada e colada três vezes. Quando um bug é consertado no Admin, a equipe esquece de atualizar o App do Cliente.

Esse caos arquitetural é o que chamamos de Dependency Hell (Inferno das Dependências).

[!WARNING] Antes de continuar: Se você é um Solo Founder ou está iniciando um novo SaaS do zero, o Turborepo pode representar uma perigosa Otimização Prematura. Leia primeiro nosso guia definitivo sobre Turborepo vs Next.js Route Groups para descobrir a forma mais ágil de escalar seu projeto no "Dia 1".

A solução adotada por gigantes como Google, Meta e Uber é a arquitetura de Monorepo: colocar todos os softwares da empresa dentro de um único e gigantesco repositório. Para fazer isso no ecossistema JavaScript sem tornar o projeto lento, nós usamos a arma secreta da Vercel: o Turborepo.


1. O Que é o Turborepo?

O Turborepo é um sistema de build (construção de código) de alta performance para Monorepos em JavaScript e TypeScript.

Ele entende a árvore de dependências do seu projeto. Se você tem uma pasta chamada packages/ui contendo o seu Design System (botões, formulários) e tanto o seu apps/admin quanto o seu apps/web consomem esses botões, o Turborepo sabe exatamente quem depende de quem.

A Magia do Cache Distribuído (Remote Caching)

O recurso mais brutal do Turborepo é o Remote Caching. Imagine que a sua equipe tem 10 desenvolvedores. Se um desenvolvedor alterar apenas o código do apps/admin e mandar o código para a nuvem da Vercel, o Turborepo percebe que o apps/web e o packages/ui não foram tocados.

A Vercel pula a etapa de compilação desses dois pacotes e pega o resultado direto do cache. O deploy (que normalmente levaria 15 minutos) cai para 10 segundos. É uma economia massiva de tempo de infraestrutura de CI/CD.


2. Estruturando o Seu Monorepo Corporativo

Vamos ver como fica a organização de pastas de um Monorepo maduro:

meu-monorepo-corporativo/
├── apps/
│   ├── admin/       (Painel Interno - Next.js)
│   ├── web/         (Site Público - Next.js)
│   └── api/         (Backend Node.js/Edge)
├── packages/
│   ├── ui/          (Design System em React compartilhado)
│   ├── config/      (Regras de ESLint e TSConfig padrão)
│   └── database/    (Schema do Prisma ORM compartilhado)
├── turbo.json       (O Cérebro do Turborepo)
└── package.json

Com essa estrutura, se você alterar a cor principal de um botão dentro de packages/ui, o site público e o painel administrativo recebem a nova cor automaticamente. Fim da duplicação de código.

Reflexo na Infraestrutura (Vercel e Domínios)

É vital entender que, ao contrário dos Route Groups, um Monorepo gera múltiplos projetos separados na nuvem:

  • Projetos Vercel: Você criará 3 projetos distintos no painel da Vercel (saas-web, saas-admin, saas-api), mas todos eles estarão apontando para o mesmo repositório do Github (apenas configurados para olhar para o seu respectivo "Root Directory" dentro de apps/).
  • Domínios Separados: Como são projetos Vercel isolados, eles devem rodar em URLs separadas (ex: seu-saas.com para a Web, app.seu-saas.com para o Dashboard, admin.seu-saas.com para o Painel Interno).
  • Deploy Independente: Se você alterar apenas um texto no Site Público, o Turborepo avisará a Vercel para fazer o deploy apenas do apps/web. Os outros dois projetos ignoram a atualização, poupando CPU e evitando quedas acidentais do sistema.

3. Mão no Código: Configuração de Alto Nível

Para orquestrar essa máquina, o arquivo turbo.json dita as regras de paralelismo e dependência. Veja um exemplo de Clean Configuration:

// turbo.json na raiz do projeto
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      // O build só acontece se os pacotes dependentes 
      // (ex: packages/ui) forem compilados antes (^build).
      "dependsOn": ["^build"],
      
      // O Turborepo guarda as pastas geradas no cache.
      // Se o código não mudar, ele reaproveita essas pastas.
      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
    },
    "lint": {
      // Tarefa de checagem de erros de código.
      "dependsOn": ["^lint"]
    },
    "dev": {
      // O modo de desenvolvimento não usa cache agressivo, 
      // ele roda eternamente ouvindo alterações.
      "cache": false,
      "persistent": true
    }
  }
}

E no package.json raiz, nós ativamos os Workspaces (suportados nativamente pelo NPM, PNPM ou Yarn) para conectar as pastas invisivelmente:

// package.json na raiz do projeto
{
  "name": "empresa-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint"
  }
}

Orquestração Perfeita

Quando você roda o comando npm run build na raiz do projeto, o Turborepo não compila um app por vez de forma linear. Ele analisa o grafo de dependências e compila tudo em paralelo usando o máximo de núcleos de CPU disponíveis na sua máquina ou no servidor, respeitando a ordem obrigatória (ex: compila o Banco de Dados e o UI System antes de compilar os Apps que dependem deles).


A Arte de Centralizar Inteligência

Construir múltiplos repositórios é o caminho dos amadores; é a fórmula perfeita para gerar retrabalho. O padrão ouro do desenvolvimento SaaS moderno é centralizar a inteligência e descentralizar as interfaces.