Slovník pojmů

Turborepo

Turborepo koordinuje projektové úlohy napříč balíčky jednoho monorepa. Neinstaluje závislosti jako package manager a nesestavuje aplikaci jako bundler; plánuje existující scripts, jejich pořadí a cache.

Stručná definice

Orchestrace úloh nad skutečnými vazbami mezi workspace balíčky.

Monorepo ukládá více aplikací a sdílených balíčků v jednom repozitáři. Package manager workspaces určují, které adresáře jsou balíčky, instalují jejich externí závislosti a propojí interní balíčky. Turborepo nad tímto package graphem sestaví task graph a rozhodne, které scripts může spustit současně a které musí čekat na výsledek závislosti.

Úlohy jako build, test nebo lint jsou skutečné scripts v package.json jednotlivých balíčků. Soubor turbo.json popisuje jejich vazby, výstupy, vstupy a cache. Turborepo tedy není package manager, bundler ani testovací framework: koordinuje nástroje, které projekt už používá přes Node.js ekosystém.

Cache uchovává výsledek úlohy pro konkrétní otisk vstupů. Při shodě může Turborepo obnovit log a deklarované výstupy místo nového běhu. Je to optimalizace, ne záruka korektnosti: chybějící environment proměnná, generovaný vstup nebo špatné outputs mohou vrátit neodpovídající artefakt.

Jaký problém řeší

Měnící se sdílený balíček nemá spustit všechno ani přeskočit dotčenou aplikaci.

S růstem monorepa přestává být správné slepě spouštět každý build a test, ale ruční výběr dotčených kroků bývá nespolehlivý. Task graph dovolí provést jen potřebnou práci ve správném pořadí.

  • build interních knihoven před buildem aplikací, které je používají
  • paralelní spuštění nezávislých testů, lintů nebo buildů
  • použití lokální cache při opakování stejné úlohy na jednom stroji
  • volitelné sdílení výsledků přes remote cache mezi vývojáři a CI
  • filtrování úloh na konkrétní package, jeho dependencies, dependents nebo změny v Gitu
  • omezení práce v CI na relevantní část repozitáře při zachování skutečných vazeb

Praktický příklad

Dvě aplikace a dva sdílené balíčky

Monorepo obsahuje apps/web, apps/admin, packages/ui a packages/config. Obě aplikace deklarují interní závislost na UI a podle potřeby také na sdílené konfiguraci. Package manager workspaces balíčky rozpoznají a propojí; Turborepo z jejich vazeb vytvoří package graph.

Konfigurace níže říká, že build balíčku musí počkat na build jeho interních dependencies. Změna packages/ui proto vede nejprve k jeho buildu a následně k buildům dotčených aplikací. Web a admin mohou po dokončení společných dependencies běžet paralelně. Nezměněný výsledek se použije z cache jen tehdy, pokud odpovídá vypočtenému otisku vstupů.

Pole outputs musí odpovídat reálným výstupům použitých nástrojů. Cesta dist/** může patřit knihovně a .next/** aplikaci v Next.js; .next/cache/** se z výsledného aplikačního artefaktu vylučuje. Jiný bundler nebo framework potřebuje jiné cesty a některá úloha nemusí vytvářet žádný cachovaný soubor.

turbo.json

{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    }
  }
}

Diagram task graphu

Změna packages/ui → build ui → build web a admin.

Zjednodušený tok předpokládá, že obě aplikace mají na UI skutečně deklarovanou interní závislost. Task graph spojuje package graph s pravidly v turbo.json a cache rozhoduje pro každý uzel samostatně.

  1. Změna packages/ui Zdrojový soubor UI vstoupí do otisku úlohy. Balíčky mimo dotčenou část grafu není nutné spouštět jen proto, že leží ve stejném repozitáři.
  2. Package graph Workspace konfigurace package manageru a interní dependencies ukážou, že apps/web a apps/admin používají packages/ui. Název adresáře sám vazbu nenahrazuje.
  3. Build ui Pravidlo dependsOn: ["^build"] řadí build interní dependency před build závislého balíčku. Pokud platný výsledek není v cache, spustí se příslušný package script.
  4. Build web a admin Po dokončení UI může Turborepo spustit nezávislé buildy obou aplikací paralelně. Každý uzel má vlastní stav, log a cache key.
  5. Lokální nebo remote cache Při cache hitu se práce přeskočí a deklarované výstupy se obnoví. Remote cache je volitelná sdílená vrstva; bez ní zůstává cache lokální pro daný stroj.

Hlavní části a koncepty

Package graph popisuje balíčky, task graph konkrétní práci.

Přesnost obou grafů rozhoduje o pořadí, paralelismu i důvěryhodnosti cache.

Apps a packages

Adresáře apps obvykle obsahují nasazované aplikace, packages sdílené knihovny nebo konfigurace. Je to užitečná konvence, ne definice monorepa ani povinná architektura Turborepa.

Package graph

Vzniká ze struktury workspaces a interních dependencies spravovaných package managerem. Turborepo jej používá k pochopení vztahů mezi balíčky, ale závislosti samo neinstaluje.

Task graph

Každá kombinace package a scriptu je uzel; dependsOn přidává pořadí mezi uzly. Prefix ^ označuje stejnou úlohu v interních dependencies, obyčejný název může vyjádřit vazbu v témže package.

Inputs, outputs a environment

Otisk musí zahrnout vše, co mění výsledek: zdroje, konfiguraci, lockfile a relevantní environment proměnné. Outputs říkají, které vzniklé soubory se mají při cache hitu obnovit.

Lokální a remote cache

Lokální cache zrychluje opakování na jednom stroji. Remote cache sdílí artefakty s týmem a CI; poskytovat ji může služba nebo kompatibilní HTTP server a vyžaduje řízení přístupu.

Filtry a incremental build

Filtr omezí spuštění na package, adresář, dependencies, dependents nebo změněnou část repozitáře. Inkrementální práce zde znamená vybrat potřebné uzly a znovu použít platné výsledky, ne automaticky částečně kompilovat vnitřek každého nástroje.

Výhody, omezení a časté chyby

Rychlost roste jen s pravdivým grafem a hermetičtějšími úlohami.

Konkrétní přínosy

  • nezávislé úlohy se mohou bezpečně spustit paralelně podle grafu
  • cache omezuje opakování drahých buildů a testů se stejnými vstupy
  • remote cache může sdílet už hotovou práci mezi lokálním vývojem a CI
  • jednotné filtry pomáhají cílit kontrolu na změněný package a jeho dependents
  • konfigurace task graphu zůstává verzovaná spolu s aplikacemi

Omezení a chyby

  • neuvedený vstup nebo environment proměnná může vytvořit nesprávný cache hit
  • chybné outputs znamenají, že se při hitu neobnoví potřebný artefakt
  • deployment nebo zápis do externí služby se nemá bezmyšlenkovitě cachovat
  • nepřesné interní dependencies rozbijí pořadí i výběr dotčených úloh
  • remote cache obsahuje build artefakty a logy, proto potřebuje přístupová a bezpečnostní pravidla
  • režie konfigurace a monorepa nemusí přinést hodnotu malému projektu

Kdy dává smysl

Pro JavaScriptové a TypeScriptové monorepo se sdíleným kódem a dražšími úlohami.

Turborepo dává smysl, když několik aplikací skutečně sdílí balíčky, tým potřebuje konzistentní build a testy a čas lze ušetřit paralelismem nebo cache. Může koordinovat knihovny i Next.js aplikace, ale Next.js nevyžaduje Turborepo a Turborepo není webový framework ani bundler.

Package manager jako npm, pnpm nebo Yarn zůstává odpovědný za instalaci, lockfile a workspaces. Turborepo nevyžaduje Yarn a jeho použití samo nevytvoří dobře navržené monorepo. Pokud projekty nesdílejí kód, release rytmus ani vlastnictví, mohou být oddělené repozitáře jednodušší. Monorepo navíc není totéž co monolitická aplikace: jeden repozitář může obsahovat více samostatně nasazovaných služeb a jeden monolit může mít jediný package.

Na co myslet

Cache je správná pouze tehdy, když klíč zachytí všechny významné vstupy.

Před zrychlováním je potřeba ověřit hranice balíčků, skutečné dependencies a reprodukovatelnost každého scriptu.

  • deklarovat interní dependencies v package manifests, ne spoléhat na umístění adresářů
  • zapsat do task konfigurace relevantní outputs, environment proměnné a nestandardní inputs
  • necachovat deploymenty a jiné úlohy s externím vedlejším efektem jako běžný čistý build
  • ověřit cache hit také v čistém pracovním adresáři, kde chybějící output nelze zakrýt lokálním souborem
  • používat jeden zvolený package manager a commitnutý lockfile pro reprodukovatelnou instalaci
  • omezit oprávnění remote cache a nezahrnovat secrets do výstupů ani logů
  • v CI měřit nejen dobu běhu, ale i cache hit rate, chyby a správnost vzniklých artefaktů

Časté otázky

Turborepo bez častých záměn

Je Turborepo package manager?

Ne. Package manager instaluje závislosti, spravuje lockfile a definuje workspaces. Turborepo nad balíčky a jejich scripts plánuje úlohy, paralelní běh a cache.

Vyžaduje Turborepo Yarn?

Ne. Pracuje s podporovanými package manager workspaces; projekt může podle své konfigurace používat například npm, pnpm nebo Yarn. Důležitá je konzistence jednoho zvoleného lockfile a workflow.

Je Turborepo bundler nebo součást Next.js?

Ne. Bundler vytváří frontendový výstup a Next.js je React framework. Turborepo může jejich scripts spustit a cachovat, ale neurčuje komponenty, routing ani podobu bundle.

Zaručuje cache správný build?

Ne. Cache věří deklarovaným a automaticky zjištěným vstupům. Pokud konfigurace vynechá významný soubor nebo environment proměnnou, může být klíč neúplný a obnovený výsledek chybný.

Je remote cache povinná?

Ne. Turborepo lze používat jen s lokální cache. Remote cache přidává sdílení mezi stroji a CI, ale také vyžaduje autentizaci, pravidla pro citlivé výstupy a důvěryhodného poskytovatele.

Jak navrhuji vývojový systém

Monorepo tooling má odpovídat skutečným vazbám mezi aplikacemi.

Při návrhu projektů odděluji role balíčků, buildů a CI tak, aby automatizace zrychlovala ověřený proces a neskrývala jeho vstupy.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.