Turborepo
Categorias

Por que usar TurboRepo

A antiga prática da “base de código compartilhada” ressurgiu agora com outro nome: monorepo. Essa estratégia consiste em armazenar o código de todos os projetos em um único repositório. Em ambientes de trabalho em que acontece integração entre projetos e componentes, isso facilita na hora de reutilizar código ou consertar falhas ao longo de toda a cadeia, fazendo um único build de todos os projetos que foram alterados.

Infelizmente, a abordagem do monorepo tende a criar repositórios imensos, complexos para serem administrados por ferramentas tradicionais, ocasionando justamente a perda da agilidade conquistada. Por causa disso, Jared Palmer (uma lenda viva da comunidade open source) criou o Turborepo, uma ferramenta de construção monorepo de código aberto focada em TypeScript e JavaScript, que poderia aumentar a velocidade de build em cerca de 65% a 85%.

Shawn Swyx Wang é um desenvolvedor / PM / investidor anjo, principalmente ativo na comunidade de desenvolvimento da web como blogueiro e palestrante frequente, evangelista do movimento Learn in Public. l. Ele é o autor de “Por que usar Tailwind CSS“, já republicado por nós. Em um novo artigo publicado na internet, ele explica como aconteceu a aquisição do Turborepo pela Vercel no ano passado e porque sua solução tem tudo para se tornar uma ferramenta essencial para os adeptos do monorepo.

Com sua autorização, traduzimos e reproduzimos o artigo na íntegra:

“O TurboRepo foi adquirido pela Vercel recentemente e eu acompanhei a excelente demonstração de introdução de Jared Palmer para ver o que está acontecendo:

Aqui estão notas rápidas para aqueles muito ocupados para ver a coisa toda, seguidas de reflexões pessoais no final.

Por que Monorepos?

Você pode consultar outras fontes para definições de Monorepos (edição de 2022: Nrwl acabou de lançar https://monorepo.tools/ que tem suas perspectivas e comparações), mas vamos gastar algum tempo explicando por que eles são um objetivo que vale a pena:

  • Você pode facilmente fazer alterações cruzadas de código em vários aplicativos (por exemplo, /frontend e /backend) em um commit atômico
  • Você pode pesquisar facilmente em todos os projetos
  • Fonte única de verdade para muitas preocupações ambientais que você desejará padronizar em toda a sua empresa, por exemplo:
    • gerenciamento de dependências (deps importantes em um package.json)
    • reutilização de código de pacotes compartilhados (por exemplo, /design-system ou /common-utils ou /schema)
    • configurações (ESlint, TSconfig, etc)
    • testes (da unidade para e2e)
  • Para autores de bibliotecas, também é mais fácil publicar pacotes com dependências entre si.

As principais ferramentas do ecossistema JS como React, Jest, pnpm, Next.js e o próprio Yarn mudaram para Monorepos, assim como pequenas startups e grandes empresas como FB e Google.

Origem do TurboRepo

A história de origem do TurboRepo começou com esta looooooonga questão aberta no TSDX de Nate Moore:

Como voluntário inicial no TSDX, evitei cuidadosamente esse problema porque nunca trabalhei em uma empresa com um grande monorepo e pensei que isso deveria ser resolvido por ferramentas dedicadas como o yarn workspace, que na época estava apenas ganhando força.

Para resolver isso, Jared tentou extrair o Lerna em uma ferramenta monorepo e, ao pesquisar como grandes lojas monorepo como Facebook e Google executavam tarefas, descobriu que muitas de suas técnicas avançadas não chegaram ao ecossistema JS maior.

Assim, o TurboRepo foi iniciado com 3 objetivos:

  • criar uma ferramenta monorepo que utilize o maior número possível dessas técnicas avançadas com configuração zero
  • facilitar a adoção incremental (por exemplo, ao mudar de Lerna)
  • certificar-se de que ele escala (por exemplo, o design da API e as opções de arquitetura são flexíveis o suficiente)

A história mais completa do TurboRepo é contada por Jared neste tópico:

O que o TurboRepo faz?

O princípio básico do TurboRepo é nunca recalcular o trabalho que foi feito antes.

Para fazer isso, ele gera um gráfico de dependência de seu pipeline de compilação a partir de uma configuração turbo em package.json, executa cada tarefa por vez e preserva uma marca da entrada/cache a saída de cada tarefa.

Quando é executado uma segunda vez, se encontrar um trabalho que corresponda a uma marca prévia, ele restaura do cache e reproduz os logs.

Como usar o TurboRepo?

A área de superfície principal da CLI é surpreendentemente pequena:

  • O comando npx [email protected] turbo-demo monta um monorepo com aplicativos (docs, web) e pacotes (sistema de design e configurações compartilhadas – eslint, tsconfig)
  • O comando turbo run build compila todos os aplicativos de uma só vez, mas o mais importante é que, quando você executa esse comando novamente, a segunda compilação é concluída em 100ms porque tudo é armazenado em cache. Há uma longa lista de sinalizadores que você pode adicionar para modificar o que o turbo run faz e produz.
  • O comando turbo prune –scope=<target> gera um monorepo esparso/parcial com um arquivo de bloqueio removido para um pacote de destino.
  • Comandos de cache remoto: login turbo e link turbo (explicado mais tarde)

A chave de configuração turbo

O TurboRepo usa uma chave especial em package.json chamada turbo (documentação aqui), e é aqui que os relacionamentos topológicos entre tarefas de build (e onde fazer a marcação digital para artefatos de cache) são definidos:

{
  "turbo": {
    "baseBranch": "origin/main",
    "pipeline": {
      "build": {
        "dependsOn": ["^build"],
        "outputs": [".next/**"]
      },
      "test": {
        "dependsOn": ["^build"],
        "outputs": []
      },
      "lint": {
        "outputs": []
      },
      "dev": {
        "cache": false
      }
    }
  }
}

Isso ajuda o Turbo a criar um Directed Acyclic Graph (Gráfico Acíclico Direcionado) de sua compilação que pode então andar no sentido inverso para compilar e verificar seu cache. Você pode até usar o sinalizador –graph para visualizar seu gráfico de construção com o Graphviz.

(Tendo experimentado ferramentas de visualização antes, esta é uma demonstração divertida, mas não praticamente tão útil 🤷‍♂️)

A outra coisa importante a saber é que você pode executar todas essas tarefas juntas e o Turbo irá paralelizar o máximo possível:

turbo run build test lint

Para entender o que está sendo executado em paralelo e depurar pipelines de compilação, você pode até mesmo fazer com que o Turbo produza um perfil com o sinalizador –profile para inspecionar os rastreamentos no Chrome DevTools!

Cache Remoto

O cache remoto é um recurso beta, mas está definido para ser de longe o ponto alto na escala do TurboRepo. Normalmente, os caches são gerados e verificados localmente, portanto, se você estiver revisando o código que um colega de trabalho escreveu, também precisará construí-lo localmente.

Parece ineficiente? Nós podemos resolver isso.

O cache remoto compartilha esse cache globalmente (isso é seguro na medida em que os hashes são seguros), transformando o TurboRepo de uma experiência de “um jogador” para um modo “multiplayer cooperativo”. A analogia que ressoa muito com os usuários é que isso é basicamente “Dropbox para seu diretório dist“.

É aqui que entra o apoio da Vercel – eles estão oferecendo cache remoto gratuito nas compilações do TurboRepo – você ainda precisará criar uma conta Vercel, e eles podem cobrar por isso mais tarde – mas isso funciona independentemente de seu aplicativo ser compilado ou hospedado em Vercel. Manobra brilhante para todos os envolvidos! Todos os usuários do TurboRepo obtêm acelerações gratuitas, a Vercel recebe várias inscrições (com efeito de rede) e uma possível fonte de receita futura.

O uso é bem simples:

npx turbo login # login to Vercel
npx turbo link

É isso! Não poderia ser mais fácil, e oferece acelerações gratuitas.

O futuro

Jared encerrou a transmissão ao vivo fazendo alguns comentários sobre o cronograma do TurboRepo:

  • Telemetria
  • Sharding Parallel Tasks em outros processos (atualmente, o TurboRepo executa tarefas paralelas no mesmo processo singlethreaded como o Node faz – para realmente fazer uso de simultaneidade total, ele deve distribuir esse trabalho para outros processos). Temporal, o projeto em que trabalho, pode ser um interessante ferramenta para isso no futuro.
  • Presets (referido como “Turbo Season 2”)
  • Recursos menores
    • Modelo de segurança pública/privada como npm
    • Modo watch mais inteligente
  • Provavelmente haverá recursos Enterprise também.

Você também pode votar em ideias de recursos na Comunidade GitHub do TurboRepo.

E o Nx?

O TurboRepo é mais frequentemente comparado ao Nx, então estou muito grato que Victor Savin (criador do Nx) escreveu uma página na documentação do Nx detalhando as diferenças que ele vê em relação ao Turborepo.

Ele também fez benchmarks para Nx vs TurboRepo que você pode experimentar:

Observações pessoais

O TurboRepo é um grande negócio para a comunidade JS não apenas porque aborda as velocidades de compilação (que sempre agradam a todos), mas também porque é uma abstração bem definida que traz muito valor fora da caixa, com um pipeline de compilação declarativo, ótimas opções de depuração/criação de perfil e ótima documentação.

Com 74% de seu código em Go, o TurboRepo é um ótimo exemplo da tese do “Systems Core, Scripting Shell“, comprovando a ideia de que a era das “ferramentas JS em JS” acabou porque a necessidade de velocidade supera as preocupações da curva de aprendizado do colaborador.

Muitas pessoas na comunidade JS (como meu antigo eu) ouviram falar sobre os benefícios dos monorepos, mas foram retidas pela falta de boas ferramentas para enfrentar esse problema de frente. Embora haja uma longa lista de ferramentas de monorepo abordando várias partes do problema, vejo o TurboRepo liderando a nova onda de ferramentas de monorepo que ganhará destaque na Terceira Era do JavaScript, graças ao forte apoio e excelente marketing de desenvolvedor de Jared e da equipe Vercel.”

Publicado originalmente como “Why TurboRepo Will Be The First Big Trend of 2022” em 27 de dezembro de 2021. Traduzido e republicado com autorização do autor.