Pracując nad złożonymi projektami oprogramowania, wybór między monorepo a polyrepo może znacząco wpłynąć na produktywność zespołu i skalowalność kodu. W tym artykule analizujemy różnice, zalety i wady każdego podejścia, i pomagamy zrozumieć, które z nich jest odpowiednie dla Ciebie.
Czym są Monorepo i Polyrepo?
Monorepo
Monorepo (monolityczne repozytorium) to pojedyncze repozytorium zawierające kod źródłowy wielu projektów, usług lub pakietów, często ze sobą powiązanych.
my-monorepo/ packages/ frontend/ backend/ shared/ package.json turbo.json
Polyrepo
Polyrepo (wiele repozytoriów) oznacza, że każdy projekt, usługa lub pakiet ma własne, oddzielne repozytorium.
repos/ frontend/ package.json backend/ package.json shared/ package.json
Różnica wizualna
Zalety i wady
Monorepo
Zalety:
- Ułatwia współdzielenie kodu (np. współdzielone biblioteki).
- Atomowy refactoring w wielu projektach.
- Centralne zarządzanie zależnościami i konfiguracjami.
Wady:
- Może stać się ciężkie w miarę wzrostu bazy kodu.
- Wymaga narzędzi do zarządzania częściowymi buildami/testami (np. Nx, Turborepo).
Polyrepo
Zalety:
- Każdy zespół/projekt jest niezależny.
- Łatwiejsze zarządzanie dla małych projektów.
- Umożliwia granularne polityki dostępu.
Wady:
- Trudniejsze współdzielenie kodu bez publikowania pakietów.
- Refactoring między repozytoriami jest bardziej złożony.
- Możliwe duplikowanie konfiguracji.
Praktyczny przykład: Monorepo z Turborepo
Załóżmy, że chcesz stworzyć monorepo z frontendem i backendem używając Turborepo.
1. Inicjalizacja monorepo
npx create-turbo@latest
2. Typowa struktura
my-monorepo/ apps/ web/ # frontend Next.js api/ # backend Node.js/Express packages/ ui/ # shared component library utils/ # shared functions turbo.json package.json
3. Przykład workspace w package.json
{ "private": true, "workspaces": [ "apps/*", "packages/*" ] }
4. Przykład importu współdzielonej biblioteki
Załóżmy, że masz funkcję w packages/utils/src/formatDate.ts:
// packages/utils/src/formatDate.ts export function formatDate(date: Date): string { return date.toLocaleDateString('en-US'); }
W frontendzie:
// apps/web/pages/index.tsx import { formatDate } from '@myorg/utils'; export default function Home() { return <div>Today is {formatDate(new Date())}</div>; }
Kiedy wybrać Monorepo?
- Średnie i duże zespoły pracujące nad wieloma powiązanymi projektami.
- Potrzeba współdzielenia kodu i przeprowadzania refactoringu na dużą skalę.
- Projekty, które szybko rosną i wymagają zoptymalizowanych buildów/testów.
Kiedy wybrać Polyrepo?
- Małe lub niezależne projekty.
- Oddzielne zespoły pracujące nad różnymi produktami.
- Bardzo restrykcyjne polityki dostępu.
Podsumowanie
Nie ma idealnego rozwiązania dla wszystkich. Wybór zależy od wielkości zespołu, złożoności projektu i potrzeb współpracy. Ważne jest, aby być świadomym kompromisów i wybrać odpowiednie narzędzia do zarządzania złożonością.