Abstraktní větvení repozitářů pro monorepo vs polyrepo se dvěma propojenými bloky kódu

Monorepo vs polyrepo: jak zvolit strukturu pro vývoj

Monorepo vs polyrepo není otázka vkusu v adresářové struktuře. Je to rozhodnutí o hranicích kódu, rychlosti CI, vlastnictví služeb, verzování balíčků a nákladech na koordinaci mezi týmy. Projdeme, kdy dává smysl jeden repozitář, kdy více repozitářů a jak poznat, že jste zvolili špatně.

Kdy strategie repozitářů začne bolet tým

Dokud na projektu pracují dva lidé a jedna aplikace, rozdíl často nepoznáte. Problém začne až ve chvíli, kdy přibude sdílená knihovna, backendová služba, administrace, mobilní klient nebo několik frontendů nad stejným API.

Repozitář určuje, jak snadno uděláte změnu napříč systémem. Například úprava validačního schématu může zasáhnout databázi, API kontrakt, webový formulář i automatické testy. V jednom modelu je to jedna změna, v druhém série navazujících pull requestů.

Rozhodnutí se proto nemá dělat podle toho, co používá Google, Meta nebo startup vedle vás. Důležité je, jak často měníte více částí produktu najednou, kolik týmů má vlastní release cyklus a jak dobře umíte udržet hranice modulů.

Monorepo: sdílený kontext bez kopírování kódu

Monorepo znamená, že více aplikací, balíčků nebo služeb žije v jednom repozitáři. Nemusí to znamenat jeden deploy ani jednu technologii. V praxi může být vedle sebe Next.js frontend, NestJS API, balíček s typy, design systém a integrační testy.

Největší výhoda je atomická změna. Když upravíte sdílený typ, komponentu nebo endpoint, můžete ve stejném pull requestu opravit všechny konzumenty. Reviewer vidí celý dopad a CI může ověřit přesně ty projekty, kterých se změna týká.

Monorepo je silné u produktů, kde části systému rostou společně. Typický příklad je SaaS aplikace s veřejným webem, administrací, API, workerem a sdíleným balíčkem pro validaci dat. Kopírování typů mezi repozitáři by tu rychle vytvořilo dluh.

Cena za pohodlí je disciplína. Jeden repozitář bez pravidel se umí změnit v hromadu implicitních závislostí. Pokud každá aplikace sahá do každého balíčku, nemáte architekturu, ale globální namespace s pomalým buildem.

Polyrepo: izolace služeb a jasné vlastnictví

Polyrepo znamená, že každá aplikace, služba nebo knihovna má vlastní repozitář. Hranice jsou tvrdší. Změna v jednom projektu se do jiného dostane přes publikovaný balíček, API verzi, Docker image nebo jiný smluvený kontrakt.

To je výhoda tam, kde týmy pracují nezávisle. Služba pro fakturaci může mít jiný release rytmus než klientská zóna. Mobilní aplikace může stabilizovat API kontrakt, zatímco backend tým dál refaktoruje interní implementaci.

Polyrepo také snižuje riziko náhodného provázání. Vývojář nemůže jen tak importovat interní utilitu z vedlejší služby. Musí vzniknout explicitní rozhraní. To někdy zpomaluje, ale u větších organizací je právě toto zpomalení užitečná kontrola.

Nevýhoda se ukáže při změnách napříč systémem. Jeden bezpečnostní fix ve sdílené knihovně může znamenat vydání nové verze balíčku, aktualizaci pěti repozitářů, pět pipeline a koordinaci release oken. Bez automatizace je to drahé.

Build systém je důležitější než počet repozitářů

Debata monorepo vs polyrepo se často zasekne na Git organizaci, ale skutečný rozdíl dělá build graf. Potřebujete vědět, co se změnilo, na čem to závisí a které testy se musí spustit. Bez toho bude velký repozitář pomalý a více repozitářů chaotických.

U monorepa se běžně používá Turborepo, Nx, Bazel nebo kombinace workspaces a vlastních skriptů. Cíl je stejný: spouštět jen dotčené úlohy, cacheovat výsledky a nebuildovat administraci kvůli změně v marketingovém webu.

Užitečný základ jsou workspace balíčky. pnpm workspaces řeší lokální linkování balíčků, jednotný lockfile a instalaci závislostí. Samy o sobě ale neřeší inteligentní pipeline ani vlastnictví modulů.

Nástroje jako dokumentace Turborepo nebo mentální model Nx přidávají dependency graph, cache a cílené příkazy. Bez těchto vrstev je monorepo často jen větší složka s více npm skripty.

Verzování a release: jeden produkt, nebo mnoho produktů

Repozitář by měl kopírovat reálný release model. Pokud se web, API a worker nasazují téměř vždy společně, monorepo zjednoduší změny i review. Pokud má každá služba vlastní životní cyklus, více repozitářů může být čistší.

Monorepo neznamená, že musíte verzovat všechno jedním číslem. Můžete mít nezávislé verze balíčků, samostatné Docker image i oddělené deploy pipeline. Důležité je, aby release proces uměl pracovat s konkrétním projektem uvnitř repozitáře.

Polyrepo naopak neznamená automaticky lepší oddělení. Pokud pět repozitářů musí být nasazeno ve stejném pořadí během jedné hodiny, jen jste přesunuli koordinaci z kódu do Slacku a CI. To obvykle zvyšuje riziko chyb.

Doporučujeme začít otázkou: kdo nese odpovědnost za produkční incident? Pokud odpověď zní jeden tým a jeden produktový tok, jeden repozitář bývá praktičtější. Pokud odpovědnost končí na hranici služby, polyrepo dává větší smysl.

CI pipeline musí měřit dopad změny, ne velikost kódu

Špatně nastavené monorepo poznáte podle toho, že každý commit spouští všechno. Lint všech aplikací, všechny unit testy, všechny E2E testy a všechny buildy. Výsledek je pomalá pipeline, kterou tým začne obcházet.

Správný model pracuje s dopadem změny. Úprava balíčku ui spustí testy konzumentů. Úprava dokumentace nespustí produkční build. Změna v databázové migraci aktivuje integrační testy backendu a kontraktové testy API.

V polyrepo světě je problém opačný. Pipeline bývají rychlejší, ale chybí celkový pohled. Zelený build v jednom repozitáři neznamená, že změna nerozbije konzumenta. Proto jsou důležité kontraktové testy, staging prostředí a kompatibilní verze API.

Pokud stavíte větší webový produkt a nechcete řešit jen repozitáře, ale i architekturu, deploy a dlouhodobou údržbu, dává smysl navázat na vývoj webových aplikací na míru. Struktura kódu má přímý dopad na cenu dalších změn.

Hranice balíčků chrání architekturu před erozí

Nejtěžší část monorepa nejsou skripty, ale hranice. Balíček shared se snadno stane odpadkovým košem pro funkce, které nikdo nechce zařadit. Po pár měsících obsahuje validace, datumové utility, API klienty, React hooky a business pravidla.

Lepší je pojmenovat balíčky podle zodpovědnosti: auth-domain, billing-client, ui-primitives, config-eslint. Název má říkat, kdo balíček vlastní a co do něj nepatří. Tím se snižuje potřeba dohadů v review.

Pomáhá také pravidlo importů. Frontend může importovat veřejný API klient, ale ne databázové typy backendu. Design systém může importovat tokeny, ale ne konkrétní business komponenty. Tato pravidla by měla kontrolovat CI, ne jen dokumentace.

V polyrepo architektuře hranice vynucuje samotný Git a package registry. To je bezpečnější, ale těžkopádnější. Každá změna veřejného rozhraní musí projít verzí, changelogem a migrací konzumentů. Pro stabilní domény je to dobrý trade-off.

Praktická konfigurace workspace pro TypeScript

Minimální monorepo pro TypeScript projekt může stát na pnpm workspaces. Typická struktura oddělí aplikace do apps a sdílené balíčky do packages. Nejde o povinný standard, ale tým se v tom rychle orientuje.

Základní konfigurace workspace je záměrně malá. Důležitější než počet souborů je konzistence názvů, jednotný lockfile a jasná pravidla, které balíčky smí být publikované a které jsou jen interní implementace produktu.

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

Interní balíček může používat protokol workspace. Tím řeknete package manageru, že závislost má být vyřešena lokálně, ne stažena z registru. Zároveň je na první pohled vidět, které části systému jsou provázané.

{
  "name": "@acme/web",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "test": "vitest run"
  },
  "dependencies": {
    "@acme/ui": "workspace:*",
    "@acme/api-client": "workspace:*"
  }
}

Nad tím můžete přidat Turborepo nebo Nx. Smyslem není mít módní nástroj, ale deklarovat úlohy a jejich závislosti. Build webu má záviset na buildu balíčků, testy mohou běžet paralelně a cache má šetřit opakovanou práci.

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "test": {
      "dependsOn": ["^build"],
      "outputs": []
    },
    "lint": {
      "outputs": []
    }
  }
}

Přístupová práva a ownership nejdou ignorovat

Polyrepo má přirozeně jednodušší přístupová práva. Dodavatel může dostat jen repozitář s mobilní aplikací, aniž by viděl backend. U monorepa musíte řešit, zda je takové sdílení vůbec přijatelné pro bezpečnostní a smluvní režim projektu.

GitHub, GitLab i Bitbucket umí code owners, protected branches a povinné review. Neřeší ale všechno. Pokud je v jednom repozitáři citlivý kód pro platby, interní administrace a veřejný web, přístupová politika musí být navržená předem.

Větší týmy by měly mít soubor typu CODEOWNERS. Ten přiřadí adresáře konkrétním týmům a vynutí review od lidí, kteří za část systému ručí. Je to jednoduchý mechanismus, ale výrazně snižuje náhodné změny mimo kompetenci autora.

# .github/CODEOWNERS
/apps/admin/        @acme/admin-team
/apps/web/          @acme/frontend-team
/packages/billing/  @acme/payments-team
/packages/ui/       @acme/design-system-team

Migrace mezi modely má být postupná, ne heroická

Přechod na monorepo má smysl, když tým opakovaně řeší synchronizaci verzí, kopírování typů a změny přes několik repozitářů. Nejlepší začátek bývá přes sdílené balíčky, ne přes kompletní přesun všeho kódu během jednoho sprintu.

Praktický postup je vybrat dvě až tři části, které se mění společně. Například web, API klienta a UI balíček. Po migraci sledujte délku CI, počet konfliktů, rychlost review a kolik změn se podaří udělat atomicky.

Opačný směr, tedy rozdělení monorepa, bývá potřeba při organizační změně. Nový tým přebírá službu, release cyklus se odděluje nebo vznikají bezpečnostní požadavky na přístup. V takovém případě nejdřív stabilizujte veřejné rozhraní.

Nedoporučujeme migrovat jen proto, že build trvá dlouho. Pomalé CI často vyřeší cache, paralelizace nebo lepší dělení testů. Změna repo strategie je architektonický zásah, ne náhrada za neudržovanou pipeline.

Rozhodovací matice pro webové aplikace a SaaS

Pokud většina změn zasahuje více částí produktu, zvažte monorepo. Pokud týmy dodávají samostatné služby s jasnými kontrakty, zvažte polyrepo. Tohle pravidlo je zjednodušené, ale v praxi funguje lépe než debata o oblíbených nástrojích.

Monorepo preferujeme pro produktové týmy, které vlastní celý tok od databáze po UI. Hodí se pro SaaS, interní systémy, marketplace, e-shopové platformy a projekty, kde se sdílí typy, komponenty a doménová logika.

Polyrepo preferujeme u samostatných služeb s nezávislým provozem, externími dodavateli nebo různými bezpečnostními režimy. Také dává smysl, pokud je jedna část systému open-source a zbytek zůstává uzavřený.

Neutrální možnost je hybrid. Například jedno monorepo pro frontendové aplikace a sdílené UI, samostatný repozitář pro platební službu a další pro datovou platformu. Hybrid není selhání, pokud hranice odpovídají provozu a vlastnictví.

Typické chyby při volbě repo architektury

První chyba je zaměnit monorepo za složku shared. Pokud jen přesunete utility do společného adresáře a nikdo nehlídá závislosti, vznikne silnější coupling než dřív. Sdílení musí mít API, vlastní testy a jasného vlastníka.

Druhá chyba je rozdělit repozitáře podle technologie místo domény. Samostatný repozitář pro všechny React komponenty, jiný pro všechny API handlery a další pro všechny typy často vytvoří horší koordinaci než jeden doménově organizovaný strom.

Třetí chyba je ignorovat lokální vývoj. Vývojář musí umět spustit relevantní část systému rychle a opakovatelně. Pokud každý onboarding začíná půldenním nastavováním symlinků, tokenů a verzí balíčků, repo strategie selhala.

Čtvrtá chyba je příliš brzká optimalizace. Malý tým nepotřebuje hned Bazel, interní registry a složitý release orchestrátor. Potřebuje jednoduchá pravidla, rychlé CI a strukturu, kterou lze rozšířit bez kompletního přepisu.

Co si z volby repozitářů odnést

Správná odpověď na monorepo vs polyrepo nevychází z počtu služeb, ale z toho, jak se mění produkt. Sledujte frekvenci společných změn, release cyklus, vlastnictví týmů, přístupová práva a schopnost automatizovat CI.

Monorepo zrychlí vývoj, když máte sdílený kontext a umíte hlídat hranice. Polyrepo pomůže, když potřebujete izolaci, nezávislost a tvrdé kontrakty. Nejhorší varianta je vybrat model bez pravidel a očekávat, že struktura repozitáře vyřeší architekturu za vás.

Začněte malým rozhodnutím, které odpovídá současnému týmu, ale neblokuje růst. Dobře navržená repo architektura sníží počet koordinačních chyb, zrychlí review a udrží náklady na změny pod kontrolou i po letech vývoje.

KATEGORIE:

SDÍLET:

Časté otázky

Kdy zvolit monorepo místo více repozitářů?
Monorepo se vyplatí, pokud jedna změna často zasahuje více částí produktu: frontend, API, sdílené typy, UI knihovnu nebo worker. Největší přínos je atomický pull request a možnost ověřit dopad změny v jedné pipeline. Není to ale zkratka k dobré architektuře. Potřebujete jasné hranice balíčků, code owners a build systém, který spouští jen dotčené úlohy.
Kdy je lepší polyrepo?
Polyrepo je vhodné pro služby s nezávislým release cyklem, samostatným týmem nebo odlišným bezpečnostním režimem. Hodí se také tam, kde potřebujete tvrdě vynutit veřejné kontrakty a nechcete, aby vývojáři importovali interní kód jiné služby. Nevýhoda je složitější koordinace změn napříč systémem, hlavně u sdílených knihoven a API verzí.
Zrychlí monorepo automaticky CI pipeline?
Monorepo samo o sobě CI nezrychlí. Rychlost přichází až s dependency graphem, cache a pravidlem, že se spouští jen úlohy ovlivněné konkrétní změnou. Bez toho může být monorepo pomalejší než více repozitářů, protože každý commit spustí zbytečně velkou část pipeline. Důležité je měřit dopad změny, ne velikost celého kódu.
Jaké nástroje použít pro TypeScript monorepo?
Pro JavaScript a TypeScript týmy bývá praktický základ pnpm workspaces nebo Yarn workspaces. Nad tím se často používá Turborepo nebo Nx, které řeší dependency graph, cache a cílené spouštění úloh. Bazel je silný u velmi velkých a technologicky různorodých repozitářů, ale má vyšší vstupní náklady. Nástroj vybírejte podle velikosti týmu a složitosti pipeline.
Může projekt kombinovat monorepo a polyrepo?
Ano, hybridní model je běžný a často rozumný. Například frontendové aplikace a design systém mohou být v jednom monorepu, zatímco platební služba nebo datová platforma běží ve vlastním repozitáři. Důležité je, aby hranice odpovídaly vlastnictví, provozu a release cyklu. Hybrid by neměl vzniknout náhodně, ale jako vědomá architektonická volba.

Komentáře (0)

Načítám komentáře...

Přidat komentář

Váš email nebude zveřejněn. Všechny komentáře procházejí schválením administrátorem.

Tento web je chráněn službou reCAPTCHA a platí Zásady ochrany osobních údajů a Smluvní podmínky společnosti Google.