Objavte silu frontendových monorepo s nástrojmi Lerna a Nx. Naučte sa spravovať pracovný priestor, zdieľať kód a efektívne buildovať rozsiahle projekty.
Frontend Monorepo: Správa pracovného priestoru pomocou Lerna a Nx
V neustále sa vyvíjajúcom svete frontendového vývoja môže byť správa veľkých a zložitých projektov významnou výzvou. Tradičné usporiadanie s viacerými repozitármi (multi-repo), hoci ponúka izoláciu, môže viesť k duplikácii kódu, problémom so správou závislostí a nekonzistentným nástrojom. Práve tu žiari architektúra monorepo. Monorepo je jediný repozitár obsahujúci viacero projektov, často súvisiacich, ktoré sa zostavujú a verzujú spoločne. Tento prístup ponúka množstvo výhod, no efektívna správa monorepa si vyžaduje špecializované nástroje. Tento článok skúma dve populárne riešenia: Lerna a Nx.
Čo je to Monorepo?
Monorepo je repozitár systému na správu verzií, ktorý obsahuje kód pre mnoho projektov. Tieto projekty môžu byť príbuzné alebo úplne nezávislé. Kľúčové je, že zdieľajú rovnaký repozitár. Spoločnosti ako Google, Facebook, Microsoft a Uber úspešne prijali monorepo na správu svojich rozsiahlych kódových základní. Predstavte si, že Google uchováva takmer všetok svoj kód, vrátane Androidu, Chrome a Gmailu, v jedinom repozitári.
Výhody Monorepo
- Zdieľanie a opätovné použitie kódu: Jednoducho zdieľajte kód medzi projektmi bez zložitých pracovných postupov balenia a publikovania. Predstavte si knižnicu dizajnového systému, ktorú je možné bezproblémovo integrovať do viacerých aplikácií v rámci toho istého repozitára.
- Zjednodušená správa závislostí: Spravujte závislosti na jednom mieste, čím sa zabezpečí konzistencia vo všetkých projektoch. Aktualizácia závislosti zdieľanej knižnice automaticky aktualizuje všetky projekty, ktoré od nej závisia.
- Atomické zmeny: Vykonávajte zmeny, ktoré sa týkajú viacerých projektov, v jedinom commite, čím sa zabezpečí konzistencia a zjednoduší testovanie. Napríklad refaktoring, ktorý ovplyvňuje frontend aj backend, sa dá urobiť atomicky.
- Zlepšená spolupráca: Tímy môžu ľahko spolupracovať na rôznych projektoch v rámci toho istého repozitára, čo podporuje zdieľanie vedomostí a medzifunkčný vývoj. Vývojári môžu ľahko prehliadať a porozumieť kódu naprieč rôznymi tímami.
- Konzistentné nástroje a postupy: Vynucujte konzistentné štandardy kódovania, pravidlá lintovania a procesy zostavovania vo všetkých projektoch. Tým sa zlepšuje kvalita a udržiavateľnosť kódu.
- Zjednodušený refaktoring: Rozsiahle refaktorovacie projekty sú zjednodušené, pretože všetok súvisiaci kód sa nachádza v rovnakom repozitári. Automatizované nástroje na refaktoring je možné použiť na celú kódovú základňu.
Výzvy Monorepo
- Veľkosť repozitára: Monorepo môže narásť do veľkých rozmerov, čo môže potenciálne spomaliť operácie klonovania a indexovania. Nástroje ako `git sparse-checkout` a `partial clone` môžu pomôcť tento problém zmierniť.
- Čas zostavenia (build time): Zostavenie celého monorepa môže byť časovo náročné, najmä pri veľkých projektoch. Nástroje ako Lerna a Nx ponúkajú optimalizované procesy zostavovania na riešenie tohto problému.
- Kontrola prístupu: Obmedzenie prístupu k špecifickým častiam monorepa môže byť zložité. Vyžaduje sa starostlivé plánovanie a implementácia mechanizmov kontroly prístupu.
- Zložitosť nástrojov: Nastavenie a správa monorepa si vyžaduje špecializované nástroje a znalosti. Učiaca sa krivka môže byť na začiatku strmá.
Lerna: Správa JavaScript projektov v Monorepo
Lerna je populárny nástroj na správu JavaScript projektov v monorepo. Optimalizuje pracovný postup okolo správy repozitárov s viacerými balíčkami pomocou Gitu a npm. Je obzvlášť vhodná pre projekty, ktoré používajú npm alebo Yarn na správu závislostí.
Kľúčové vlastnosti Lerna
- Správa verzií: Lerna dokáže automaticky verzovať a publikovať balíčky na základe zmien vykonaných od posledného vydania. Používa konvenčné commity na určenie nasledujúceho čísla verzie.
- Správa závislostí: Lerna sa stará o závislosti medzi balíčkami a zabezpečuje, aby balíčky v rámci monorepa mohli závisieť jeden od druhého. Na vytvorenie lokálnych závislostí používa symbolické odkazy (symlinking).
- Spúšťanie úloh: Lerna dokáže spúšťať príkazy naprieč viacerými balíčkami paralelne, čím urýchľuje procesy zostavovania a testovania. Podporuje spúšťanie skriptov definovaných v `package.json`.
- Detekcia zmien: Lerna dokáže zistiť, ktoré balíčky sa zmenili od posledného vydania, čo umožňuje cielené zostavenie a nasadenie.
Príklad použitia Lerna
Ukážme si použitie Lerna na zjednodušenom príklade. Predpokladajme, že máme monorepo s dvoma balíčkami: `package-a` a `package-b`. `package-b` závisí od `package-a`.
monorepo/
├── lerna.json
├── package.json
├── packages/
│ ├── package-a/
│ │ ├── package.json
│ │ └── index.js
│ └── package-b/
│ ├── package.json
│ └── index.js
1. Inicializácia Lerna:
lerna init
Tento príkaz vytvorí `lerna.json` a aktualizuje koreňový `package.json`. Súbor `lerna.json` konfiguruje správanie Lerny.
2. Inštalácia závislostí:
npm install
# alebo
yarn install
Týmto sa nainštalujú závislosti pre všetky balíčky v monorepo na základe súborov `package.json` v každom balíčku.
3. Spustenie príkazu naprieč balíčkami:
lerna run test
Tento príkaz spustí skript `test` definovaný v súboroch `package.json` všetkých balíčkov, ktoré ho majú definovaný.
4. Publikovanie balíčkov:
lerna publish
Tento príkaz analyzuje históriu commitov, určí, ktoré balíčky sa zmenili, zvýši ich verzie na základe konvenčných commitov a publikuje ich na npm (alebo do vami zvoleného registra).
Konfigurácia Lerna
Súbor `lerna.json` je srdcom konfigurácie Lerna. Umožňuje vám prispôsobiť správanie Lerny, ako napríklad:
- `packages`: Špecifikuje umiestnenie balíčkov v rámci monorepa. Často sa nastavuje na `["packages/*"]`.
- `version`: Špecifikuje stratégiu verziovania. Môže byť `independent` (každý balíček má vlastnú verziu) alebo pevná verzia.
- `command`: Umožňuje konfigurovať možnosti pre špecifické príkazy Lerna, ako sú `publish` a `run`.
Príklad `lerna.json`:
{
"packages": [
"packages/*"
],
"version": "independent",
"npmClient": "npm",
"useWorkspaces": true,
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore(release): publish"
}
}
}
Nx: Inteligentný, rýchly a rozšíriteľný build systém
Nx je výkonný build systém, ktorý poskytuje pokročilé funkcie pre správu monorepo. Zameriava sa na inkrementálne buildy, ukladanie výsledkov do cache (computation caching) a orchestráciu úloh, aby výrazne zlepšil časy zostavenia a produktivitu vývojárov. Zatiaľ čo Lerna sa primárne zameriava na správu balíčkov, Nx poskytuje komplexnejší prístup k správe celého pracovného postupu monorepa, vrátane generovania kódu, lintovania, testovania a nasadenia.
Kľúčové vlastnosti Nx
- Inkrementálne buildy: Nx analyzuje graf závislostí vašich projektov a znovu zostaví iba tie projekty, ktoré sa zmenili od posledného buildu. To dramaticky skracuje časy zostavenia.
- Ukladanie výsledkov do cache (Computation Caching): Nx ukladá výsledky úloh, ako sú buildy a testy, do cache, aby ich bolo možné znovu použiť, ak sa vstupy nezmenili. To ďalej urýchľuje vývojové cykly.
- Orchestrácia úloh: Nx poskytuje výkonný systém orchestrácie úloh, ktorý vám umožňuje definovať zložité buildovacie pipeline a efektívne ich vykonávať.
- Generovanie kódu: Nx poskytuje nástroje na generovanie kódu, ktoré vám môžu pomôcť rýchlo vytvárať nové projekty, komponenty a moduly podľa osvedčených postupov a konzistentných štandardov.
- Ekosystém pluginov: Nx má bohatý ekosystém pluginov, ktorý podporuje rôzne technológie a frameworky, ako sú React, Angular, Node.js, NestJS a ďalšie.
- Vizualizácia grafu závislostí: Nx dokáže vizualizovať graf závislostí vášho monorepa, čo vám pomôže pochopiť vzťahy medzi projektmi a identifikovať potenciálne problémy.
- Príkazy pre ovplyvnené časti (Affected Commands): Nx poskytuje príkazy na spustenie úloh iba na projektoch, ktoré sú ovplyvnené konkrétnou zmenou. To vám umožňuje sústrediť svoje úsilie na oblasti, ktoré si vyžadujú pozornosť.
Príklad použitia Nx
Ukážme si použitie Nx na zjednodušenom príklade. Vytvoríme monorepo s React aplikáciou a Node.js knižnicou.
1. Globálna inštalácia Nx CLI:
npm install -g create-nx-workspace
2. Vytvorenie nového Nx pracovného priestoru:
create-nx-workspace my-monorepo --preset=react
cd my-monorepo
Týmto sa vytvorí nový Nx pracovný priestor s React aplikáciou. Voľba `--preset=react` povie Nx, aby inicializoval pracovný priestor s konfiguráciami špecifickými pre React.
3. Generovanie knižnice:
nx generate @nrwl/node:library my-library
Týmto sa vygeneruje nová Node.js knižnica s názvom `my-library`. Nx automaticky nakonfiguruje knižnicu a jej závislosti.
4. Zostavenie (build) aplikácie:
nx build my-app
Týmto sa zostaví React aplikácia. Nx analyzuje graf závislostí a znovu zostaví iba potrebné súbory.
5. Spustenie testov:
nx test my-app
Týmto sa spustia jednotkové testy pre React aplikáciu. Nx ukladá výsledky testov do cache, aby urýchlil nasledujúce spustenia testov.
6. Zobrazenie grafu závislostí:
nx graph
Tento príkaz otvorí webové rozhranie, ktoré vizualizuje graf závislostí monorepa.
Konfigurácia Nx
Nx sa konfiguruje prostredníctvom súboru `nx.json`, ktorý sa nachádza v koreňovom adresári pracovného priestoru. Tento súbor definuje projekty v pracovnom priestore, ich závislosti a úlohy, ktoré sa na nich môžu vykonávať.
Kľúčové možnosti konfigurácie v `nx.json` zahŕňajú:
- `projects`: Definuje projekty v pracovnom priestore a ich konfiguráciu, ako je ich koreňový adresár a ciele zostavenia (build targets).
- `tasksRunnerOptions`: Konfiguruje spúšťač úloh (task runner), ktorý je zodpovedný za vykonávanie úloh a ukladanie ich výsledkov do cache.
- `affected`: Konfiguruje, ako Nx určuje, ktoré projekty sú ovplyvnené zmenou.
Príklad `nx.json`:
{
"npmScope": "my-org",
"affected": {
"defaultBase": "main"
},
"implicitDependencies": {
"package.json": {
"dependencies": "*",
"devDependencies": "*"
},
".eslintrc.json": "*"
},
"tasksRunnerOptions": {
"default": {
"runner": "nx-cloud",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"],
"accessToken": "...",
"canTrackAnalytics": false,
"showUsageWarnings": false
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"inputs": ["production", "default"],
"outputs": ["{projectRoot}/dist"]
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "!{projectRoot}/dist/**/*", "!{projectRoot}/tmp/**/*"],
"production": ["!{projectRoot}/**/*.spec.ts", "!{projectRoot}/**/*.spec.tsx", "!{projectRoot}/**/*.spec.js", "!{projectRoot}/**/*.spec.jsx"]
},
"generators": {
"@nrwl/react": {
"application": {
"style": "css",
"linter": "eslint",
"unitTestRunner": "jest"
},
"library": {
"style": "css",
"linter": "eslint",
"unitTestRunner": "jest"
},
"component": {
"style": "css"
}
},
}
}
Lerna vs. Nx: Ktorý si vybrať?
Lerna aj Nx sú vynikajúce nástroje na správu frontendových monorepo, ale zameriavajú sa na mierne odlišné potreby. Tu je porovnanie, ktoré vám pomôže vybrať ten správny pre váš projekt:
| Vlastnosť | Lerna | Nx |
|---|---|---|
| Zameranie | Správa balíčkov | Build systém a orchestrácia úloh |
| Inkrementálne buildy | Obmedzené (vyžaduje externé nástroje) | Vstavané a vysoko optimalizované |
| Ukladanie výsledkov do cache | Nie | Áno |
| Generovanie kódu | Nie | Áno |
| Ekosystém pluginov | Obmedzený | Rozsiahly |
| Učiaca sa krivka | Nižšia | Vyššia |
| Zložitosť | Jednoduchší | Zložitejší |
| Prípady použitia | Projekty zamerané primárne na správu a publikovanie npm balíčkov. | Veľké a zložité projekty vyžadujúce optimalizované časy zostavenia, generovanie kódu a komplexný build systém. |
Vyberte si Lerna, ak:
- Potrebujete primárne spravovať a publikovať npm balíčky.
- Váš projekt je relatívne malý až stredne veľký.
- Uprednostňujete jednoduchší nástroj s nižšou učiacou sa krivkou.
- Už ste oboznámení s npm a Yarn.
Vyberte si Nx, ak:
- Potrebujete optimalizované časy zostavenia a inkrementálne buildy.
- Chcete možnosti generovania kódu.
- Vyžadujete komplexný build systém s orchestráciou úloh.
- Váš projekt je veľký a zložitý.
- Ste ochotní investovať čas do učenia sa výkonnejšieho nástroja.
Môžete používať Lerna s Nx?
Áno, Lerna a Nx sa dajú používať spoločne. Táto kombinácia vám umožňuje využiť schopnosti Lerna v oblasti správy balíčkov a zároveň profitovať z optimalizovaného build systému a orchestrácie úloh Nx. Nx môže byť nakonfigurovaný ako spúšťač úloh pre Lerna, čím poskytuje inkrementálne buildy a ukladanie výsledkov do cache pre balíčky spravované Lernou.
Najlepšie postupy pre správu frontendového Monorepo
Bez ohľadu na to, či si vyberiete Lerna alebo Nx, dodržiavanie osvedčených postupov je kľúčové pre úspešnú správu frontendového monorepa:
- Vytvorte jasnú štruktúru projektu: Organizujte svoje projekty logicky a konzistentne. Používajte jasnú konvenciu pomenovania pre balíčky a knižnice.
- Vynucujte konzistentné štandardy kódovania: Používajte lintery a formátovače na zabezpečenie konzistentného štýlu kódu vo všetkých projektoch. Nástroje ako ESLint a Prettier je možné integrovať do vášho pracovného postupu.
- Automatizujte procesy zostavenia a testovania: Používajte CI/CD pipeline na automatizáciu procesov zostavovania, testovania a nasadzovania. Môžete použiť nástroje ako Jenkins, CircleCI a GitHub Actions.
- Implementujte revízie kódu (Code Reviews): Vykonávajte dôkladné revízie kódu, aby ste zabezpečili jeho kvalitu a udržiavateľnosť. Používajte pull requesty a nástroje na revíziu kódu.
- Monitorujte časy zostavenia a výkon: Sledujte časy zostavenia a metriky výkonu, aby ste identifikovali úzke miesta a oblasti na zlepšenie. Nx poskytuje nástroje na analýzu výkonu buildov.
- Dokumentujte štruktúru a procesy vášho monorepo: Vytvorte jasnú dokumentáciu, ktorá vysvetľuje štruktúru vášho monorepa, použité nástroje a technológie a vývojové pracovné postupy.
- Osvojte si konvenčné commity: Používajte konvenčné commity na automatizáciu procesov verziovania a vydávania. Lerna podporuje konvenčné commity priamo z krabice.
Záver
Frontendové monorepo ponúkajú významné výhody pre správu veľkých a zložitých projektov, vrátane zdieľania kódu, zjednodušenej správy závislostí a zlepšenej spolupráce. Lerna a Nx sú výkonné nástroje, ktoré vám môžu pomôcť efektívne spravovať frontendové monorepo. Lerna je skvelou voľbou pre správu npm balíčkov, zatiaľ čo Nx poskytuje komplexnejší build systém s pokročilými funkciami, ako sú inkrementálne buildy a generovanie kódu. Dôkladným zvážením potrieb vášho projektu a dodržiavaním osvedčených postupov môžete úspešne prijať frontendové monorepo a využívať jeho výhody.
Nezabudnite zvážiť faktory, ako sú skúsenosti vášho tímu, zložitosť projektu a požiadavky na výkon pri výbere medzi Lernou a Nx. Experimentujte s oboma nástrojmi a nájdite ten, ktorý najlepšie vyhovuje vašim špecifickým potrebám.
Veľa šťastia na vašej ceste s monorepo!