Úvod Prečo práve Monorepo? V dnešnej dobe nemožno poprieť rýchly vývoj vývoja softvéru. Tímy rastú, projekty bývajú komplexnejšie. Spoločnosti vynakladajú značné prostriedky na udržiavanie distribuovanej kódovej základne pozostávajúcej z mnohých fragmentov. Vstúpte do monorepo – jediného zjednoteného úložiska, ktoré spája celý váš kód. Monorepos nie je ani zďaleka trendom, ale v poslednej dobe sa stal architektonickým prístupom na umiestnenie celej kódovej základne na jednom mieste. Tímy získajú vylepšené zdieľanie kontextu, hladkú spoluprácu a nástroj, ktorý prirodzene podporuje opätovné použitie kódu. Nastavenie pracovných priestorov priadze Poznámka: Vždy, keď sa v tomto článku spomína slovo „Priadza“, vzťahuje sa to konkrétne na priadzu v4 – najnovšiu verziu, ktorá ponúka vylepšené možnosti a lepší výkon. Čo sú pracovné priestory priadze? Pracovné priestory sú balíčky monorepo, často nazývané balíčky. Pomáhajú vám bez námahy spravovať viacero balíkov v jednom úložisku. S pracovnými priestormi. môžete: Jednoduché zdieľanie závislostí: Bezproblémovo zdieľajte bežné závislosti vo svojom projekte. Zjednodušte správu závislostí: Priadza automaticky spája miestne balíky, čím sa znižuje duplicita a uľahčuje vývoj. Urýchliť inštalácie: Využite optimalizáciu výkonu Yarn a mechanizmy ukladania do vyrovnávacej pamäte (tj ). vstavaný plug'n'play Zlepšenie kontroly nad Monorepo: Definujte (pravidlá) a použite na udržanie konzistencie. obmedzenia desiatky dostupných pluginov Aj keď je Yarn vybraným manažérom pre tento článok vďaka svojej jednoduchosti, rýchlosti a rozsiahlym možnostiam konfigurácie – je dôležité si uvedomiť, že správna voľba závisí od konkrétnych potrieb vášho projektu, preferencií tímu a celkového pracovného postupu. Napríklad a sú ďalšie moderné nástroje, ktoré ponúkajú širokú škálu funkcií. PNPM Turborepo Počiatočná konfigurácia Nastavenie priadze je jednoduchý proces. Pri inštalácii a konfigurácii priadze vo svojom projekte postupujte podľa oficiálneho sprievodcu: . Sprievodca inštaláciou priadze Po dokončení inštalácie prejdime ku konfigurácii. Keďže používame plug'n'play, musíte sa uistiť, že vaše IDE správne rozpoznáva závislosti. Ak používate VSCode, spustite: # Typescript is required for VSCode SDK to set up correctly yarn add -D typescript@^5 yarn dlx @yarnpkg/sdks vscode Ak používate iný editor kódu, skontrolujte dostupné súpravy SDK tu: . Súpravy SDK Editor priadze V tomto bode ste pripravení začať používať priadzu. Organizovanie štruktúry Monorepo Teraz, keď je správca balíkov nakonfigurovaný, je čas navrhnúť škálovateľnú organizáciu projektu. Jasná, dobre definovaná štruktúra nielenže uľahčuje navigáciu v úložisku, ale tiež podporuje lepšie opätovné použitie kódu. V tomto príklade rozdelíme kódovú základňu do troch hlavných kategórií: : Aplikácie Klient: Obsahuje finálne nasaditeľné klientske produkty. Server: Obsahuje finálne nasaditeľné serverové produkty. : Vlastnosti Klient: Pre samostatné widgety používateľského rozhrania. Server: Pre samostatné časti backendovej obchodnej logiky. : Liby Obsahuje zdieľaný kód, ako sú komponenty návrhového systému, konštanty, aktíva a pomocné programy. Toto je bezkontextová zóna na ukladanie opakovane použiteľnej logiky. Aby sme demonštrovali silu tejto štruktúry priečinkov, začnime pridaním týchto hlavných priečinkov do zoznamu pracovných priestorov Yarnu. Do koreňového súboru package.json pridajte nasledovné: "workspaces": [ "apps/**", "features/**", "libs/**" ] Táto konfigurácia povie Yarnu, aby s balíkmi v týchto priečinkoch zaobchádzal ako s lokálnymi balíkmi. Následné inštalácie zabezpečia, aby boli závislosti pre každý balík správne nastavené a prepojené. Bootstrapping Codebase V tejto časti si prejdeme minimálny príklad kódovej základne, ktorý ilustruje, ako zaviesť monorepo. Namiesto úplných útržkov kódu uvediem krátke príklady s odkazmi na úplné súbory v . úložisku vytvorenom špeciálne pre tento článok Bootstrapping serverovej aplikácie Začíname s jednoduchým na autentifikáciu používateľov. Táto serverová aplikácia odhaľuje jeden koncový bod ( ), ktorý využíva obsluhu z iného balíka. Express API /auth/signIn import express from "express"; import cors from "cors"; import { signInHandler } from "@robust-monorepo-yarn-nx-changesets/sign-in-handler"; const app = express(); const port = process.env.PORT || 1234; app.use(express.json()); app.use( cors({ origin: process.env.CORS_ORIGIN || "http://localhost:3000", }) ); app.post("/auth/signIn", signInHandler); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); Odkaz na balík Ako vidíte, koncový bod používa obslužný program importovaný z iného balíka. To nás privádza k nášmu ďalšiemu komponentu: funkcii servera. /auth/signIn Funkcia bootstrapping servera Funkcia servera zahŕňa logiku autentifikácie. V tomto balíku definujeme obslužný program prihlásenia, ktorý využíva zdieľaný overovací nástroj z knižnice. import type { RequestHandler } from "express"; import { passwordValidator, usernameValidator, } from "@robust-monorepo-yarn-nx-changesets/validator"; const signInHandler: RequestHandler = (req, res) => { if (!req.body) { res.status(422).send("Request body is missing"); return; } if (typeof req.body !== "object") { res.status(422).send("Request body expected to be an object"); return; } const { username, password } = req.body; const usernameValidationResult = usernameValidator(username); if (typeof usernameValidationResult === "string") { res .status(422) .send("Invalid username format: " + usernameValidationResult); return; } const passwordValidationResult = passwordValidator(password); if (typeof passwordValidationResult === "string") { res .status(422) .send("Invalid password format: " + passwordValidationResult); return; } // Emulate a successful sign-in if (username === "test" && password === "test1234") { res.status(200).send("Sign in successful"); return; } return res.status(422).send("Username or password is incorrect"); }; export default signInHandler; Odkaz na balík Tento prístup zhŕňa logiku autentifikácie vo svojom vlastnom balíku, čo umožňuje jej nezávislý vývoj a údržbu. Všimnite si, ako sa nástroje validátora importujú zo . zdieľanej knižnice Bootstrapping klientskej aplikácie Ďalej sa pozrime na stranu klienta. V našej klientskej aplikácii vytvárame jednoduchú webovú stránku, ktorá umožňuje autentifikáciu používateľa vyvolaním serverového API. "use client"; import { SignInForm } from "@robust-monorepo-yarn-nx-changesets/sign-in-form"; const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:1234"; export default function Home() { const handleSubmit = async (username: string, password: string) => { const response = await fetch(`${API_URL}/auth/signIn`, { method: "POST", body: JSON.stringify({ username, password }), headers: { "Content-Type": "application/json", }, }); if (response.status === 200) { alert("Sign in successful"); return; } if (response.status === 422) { alert("Sign in failed: " + (await response.text())); return; } alert("Sign in failed"); }; return ( <div className="w-full h-screen overflow-hidden flex items-center justify-center"> <SignInForm onSubmit={handleSubmit} /> </div> ); } Odkaz na balík V tomto príklade je komponent importovaný z balíka funkcií klienta, čo nás vedie k nášmu konečnému komponentu. SignInForm Bootstrapping Client Funkcia Balík funkcií klienta poskytuje autentifikačný formulár spolu so zdieľanou logikou overovania. Tým sa zabráni duplicite kódu a zabezpečí sa konzistentnosť. import { passwordValidator, usernameValidator, } from "@robust-monorepo-yarn-nx-changesets/validator"; interface SignInFormProps { onSubmit: (username: string, password: string) => void; } const SignInForm = ({ onSubmit }: SignInFormProps) => { const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); const username = (event.currentTarget[0] as HTMLInputElement).value; const usernameValidationResult = usernameValidator(username); if (typeof usernameValidationResult === "string") { alert(usernameValidationResult); return; } const password = (event.currentTarget[1] as HTMLInputElement).value; const passwordValidationResult = passwordValidator(password); if (typeof passwordValidationResult === "string") { alert(passwordValidationResult); return; } onSubmit(username!, password!); }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Username" /> <input type="password" placeholder="Password" /> <button type="submit">Submit</button> </form> ); }; export default SignInForm; Odkaz na balík Tu opäť vidíme použitie z našich zdieľaných knižníc, čo zaisťuje, že logika overovania je centralizovaná a ľahko udržiavaná. validátora To je všetko pre náš príklad minimálnej kódovej základne. Majte na pamäti, že tento kód je zjednodušenou ilustráciou, ktorá má demonštrovať základnú štruktúru a prepojenie medzi aplikáciami, funkciami a knižnicami v monorepo. Tieto príklady môžete podľa potreby rozšíriť, aby vyhovovali špecifickým požiadavkám vášho projektu. Spúšťanie skriptov pomocou NX Správa skriptov v monorepo môže byť náročná. Aj keď vám Yarn umožňuje s použitím rôznych podmienok, môže to vyžadovať vlastné skriptovanie pre podrobnejšie ovládanie. Tu prichádza na scénu NX: poskytuje hotové riešenie na efektívne a cielené vykonávanie skriptov. spúšťať skripty vo viacerých balíkoch Úvod do NX NX je zostavovací systém optimalizovaný pre monorepo s pokročilými možnosťami CI. S NX môžete: : Využite súbežnosť na zrýchlenie svojich stavieb. Efektívne spúšťajte úlohy paralelne : Pochopte prepojenia medzi balíkmi a skriptmi. Identifikujte vzťahy závislostí : Vyhnite sa nadbytočnej práci ukladaním výstupov do vyrovnávacej pamäte. Výsledky spustenia skriptu vo vyrovnávacej pamäti Rozšírte funkčnosť prostredníctvom . Prispôsobenie správania pomocou doplnkov: bohatého ekosystému doplnkov Cielené spustenie skriptu Aby sme mohli využiť schopnosti NX, musíme najprv vytvoriť súbor , aby sme definovali súbor pravidiel pre naše skripty. Nižšie je uvedený príklad konfigurácie: nx.json { "targetDefaults": { "build": { "dependsOn": [ "^build" ], "outputs": [ "{projectRoot}/dist" ], "cache": true }, "typecheck": { "dependsOn": [ "^build", "^typecheck" ] }, "lint": { "dependsOn": [ "^build", "^lint" ] } }, "defaultBase": "main" } V jednoduchej angličtine táto konfigurácia znamená: Stavať skript pre balík závisí od úspešného zostavenia jeho závislostí a jeho výstup sa ukladá do vyrovnávacej pamäte. build Typová kontrola Skript balíka závisí od skriptov na zostavenie a kontrolu typov jeho závislostí. typecheck Lint Skript pre balík závisí od skriptov build aj lint jeho závislostí. lint Teraz pridajme skripty do : package.json "scripts": { "build:all": "yarn nx run-many -t build", "build:affected": "yarn nx affected -t build --base=${BASE:-origin/main} --head=${HEAD:-HEAD}", "typecheck:all": "yarn nx run-many -t typecheck", "typecheck:affected": "yarn nx affected -t typecheck --base=${BASE:-origin/main} --head=${HEAD:-HEAD}", "lint:all": "yarn nx run-many -t lint", "lint:affected": "yarn nx affected -t lint --base=${BASE:-origin/main} --head=${HEAD:-HEAD}", "quality:all": "yarn nx run-many --targets=typecheck,lint", "quality:affected": "yarn nx affected --targets=typecheck,lint --base=${BASE:-origin/main} --head=${HEAD:-HEAD}" } Tu definujeme štyri typy vykonávacích skriptov: zostaví balík. build: Kontroluje typy balíka. typecheck: práši balík. chuchvalce: Spustí kontrolu písma aj vlákna.' kvalita: Každý skript má dve variácie: Spustí skript na všetkých balíkoch. all: Spustí skript iba na balíkoch ovplyvnených nedávnymi zmenami. Premenné prostredia a vám umožňujú špecifikovať rozsah (predvolený je a aktuálny ), čo umožňuje podrobné vykonávanie požiadaviek na stiahnutie. To môže výrazne ušetriť čas a zdroje. ovplyvnené: BASE HEAD origin/main HEAD Správa kruhových závislostí NX tiež poskytuje na generovanie grafu závislosti, ktorý môže pomôcť pri detekcii cyklov závislosti. Nasledujúci skript používa výstup grafu NX na kontrolu kruhových závislostí a zlyhá, ak sa nejaké nájdu. vstavaný príkaz Vytvorte súbor na s nasledujúcim obsahom: scripts/check-circulardeps.mjs import { execSync } from "child_process"; import path from "path"; import fs from "fs"; const hasCycle = (node, graph, visited, stack, path) => { if (!visited.has(node)) { visited.add(node); stack.add(node); path.push(node); const dependencies = graph.dependencies[node] || []; for (const dep of dependencies) { const depNode = dep.target; if ( !visited.has(depNode) && hasCycle(depNode, graph, visited, stack, path) ) { return true; } if (stack.has(depNode)) { path.push(depNode); return true; } } } stack.delete(node); path.pop(); return false; }; const getGraph = () => { const cwd = process.cwd(); const tempOutputFilePath = path.join(cwd, "nx-graph.json"); execSync(`nx graph --file=${tempOutputFilePath}`, { encoding: "utf-8", }); const output = fs.readFileSync(tempOutputFilePath, "utf-8"); fs.rmSync(tempOutputFilePath); return JSON.parse(output).graph; }; const checkCircularDeps = () => { const graph = getGraph(); const visited = new Set(); const stack = new Set(); for (const node of Object.keys(graph.dependencies)) { const path = []; if (hasCycle(node, graph, visited, stack, path)) { console.error("🔴 Circular dependency detected:", path.join(" → ")); process.exit(1); } } console.log("✅ No circular dependencies detected."); }; checkCircularDeps(); Tento skript: Vykoná príkaz NX na vygenerovanie grafu závislosti. Prečíta graf z dočasného súboru JSON. Rekurzívne kontroluje cykly. Zaznamená chybu a ukončí sa, ak sa zistí kruhová závislosť. Overenie závislostí s obmedzeniami priadze Ako projekty rastú, udržiavanie konzistentnosti medzi závislosťami sa stáva náročným. Presadzovanie prísnych pravidiel týkajúcich sa závislostí, verzií uzlov a iných konfigurácií je nevyhnutné, aby sa predišlo zbytočnému technickému dlhu. Obmedzenia priadze ponúkajú spôsob, ako automatizovať tieto overenia. Pochopenie obmedzení priadze Obmedzenia priadze sú súbor pravidiel pre balíky vo vašom monorepo. Významnou výhodou ich používania je, že ste správcom týchto pravidiel. Môžete napríklad vytvoriť pravidlo, ktoré prinúti všetky balíky používať rovnakú verziu Reactu. Po nastavení už nikdy nenarazíte na problém, keď hostiteľská aplikácia nemôže používať funkciu/lib s vyššou verziou Reactu. Hoci migrácia veľkého monorepo na novú hlavnú verziu závislosti môže byť zložitá, používanie obmedzení v konečnom dôsledku prináša konzistenciu a stabilitu celého projektu. Presadzovanie konzistentnosti V našom vzorovom úložisku používame súbor na vynútenie konzistencie pre: yarn.config.cjs Verzia uzla Verzia priadze Verzie závislostí Na umožnenie flexibility počas prechodov môžete definovať vylúčenia na dočasné obídenie určitých kontrol. Napríklad: const workspaceCheckExclusions = []; const dependencyCheckExclusions = []; Tieto konštanty vám umožňujú vylúčiť špecifické pracovné priestory alebo závislosti z procesu overovania, čím sa v prípade potreby zaistí hladká migrácia. Správa verzií so sadami zmien Ďalším problémom, s ktorým sa môžete stretnúť pri raste úložiska, je správa verzií a ich uvoľňovanie. Sady zmien poskytujú elegantné riešenie na automatizáciu tohto procesu a zabezpečujú, že každá zmena bude sledovaná, aktualizovaná a uvoľnená. Úvod do sady zmien je open-source nástroj určený na správu verzií v monorepo úložiskách. Zjednodušuje proces sledovania zmien tým, že ich rozdeľuje do malých, ľudsky čitateľných dokumentov, ktoré zachytávajú zámer zmeny. Tieto dokumenty sa nazývajú changesety. Medzi hlavné výhody patrí: Changesets Prehľadná dokumentácia Každá sada zmien popisuje vykonané zmeny, čo pomáha vývojárom aj spotrebiteľom pochopiť, čo môžu od nového vydania očakávať. Granulovaná kontrola verzií Verzia každého balíka je nezávislá, čím sa zabezpečí, že sa aktualizujú iba príslušné balíky. To minimalizuje riziko nárazov prázdnych verzií a prerušenia závislostí. Priateľská spolupráca Keďže každá zmena je zaznamenaná prostredníctvom sady zmien, tímy môžu skontrolovať a schváliť aktualizácie pred samotným vydaním. Automatizácia uvoľňovania Jednou z najvýkonnejších funkcií Changesets je schopnosť automatizovať proces. Sady zmien môžete integrovať do svojho kanála CI/CD a zabudnúť na manuálne zmeny verzií a publikovanie NPM. Pozrite sa na pracovný postup vo vzorovom úložisku. Má krok . Krok podporovaný GitHub akcia vytvára celé kúzlo. Na zverejňovanie balíkov musíte nastaviť iba . Potom každé zatlačenie do vetvy: release.yaml create-release-pull-request-or-publish changesets/akciou NPM_TOKEN main . Skontrolujte, či existujú nejaké dokumenty Changeset Ak sú k dispozícii dokumenty changesetov, akcia vytvorí požiadavku na stiahnutie s potrebnými zmenami verzie a aktualizáciami protokolu zmien. Ak sa nezistia žiadne zmeny, nič sa nedeje. . Skontrolujte, či sú nejaké balíčky pripravené na zverejnenie Ak sú balíčky pripravené na vydanie, akcia zverejní nové verzie do NPM pomocou poskytnutého . Ak nie sú žiadne balíčky pripravené na zverejnenie, akcia sa ukončí bez vykonania zmien. NPM_TOKEN Automatizáciou týchto úloh zaisťujú sady zmien, že vaše vydania sú konzistentné a spoľahlivé, čím sa znižuje možnosť ľudskej chyby a zefektívňuje sa váš pracovný postup vývoja. Integrácia pracovného toku s akciami GitHub Táto časť sa ponorí do toho, ako uvoľniť silu architektúry, ktorú sme práve vytvorili. Pomocou akcií GitHub zautomatizujeme kontroly kvality PR, vydania verzií pre knižnice a funkcie a nasadenie aplikácií. Dôraz je kladený na maximalizáciu automatizácie pri zachovaní kvality kódu a granularity úloh. Overte kvalitu PR Aby sme zabezpečili, že kód žiadosti o stiahnutie zostane konzistentný a stabilný, vytvárame vyhradený pracovný postup . Tento pracovný postup vykonáva niekoľko úloh, ako je napríklad zabezpečenie toho, aby sa nezavádzali manuálne zmeny verzií (keďže vytváranie verzií riadia sady zmien): quality.yaml - id: check_version name: Check version changes run: | BASE_BRANCH=${{ github.event.pull_request.base.ref }} git fetch origin $BASE_BRANCH CHANGED_FILES=$(git diff --name-only origin/$BASE_BRANCH HEAD) VERSION_CHANGED=false for FILE in $CHANGED_FILES; do if [[ $FILE == */package.json ]]; then if [ -f "$FILE" ]; then HEAD_VERSION=$(grep '"version":' "$FILE" | awk -F '"' '{print $4}') else continue fi HEAD_VERSION=$(cat $FILE | grep '"version":' | awk -F '"' '{print $4}') if git cat-file -e origin/$BASE_BRANCH:$FILE 2>/dev/null; then BASE_VERSION=$(git show origin/$BASE_BRANCH:$FILE | grep '"version":' | awk -F '"' '{print $4}') else BASE_VERSION=$HEAD_VERSION fi if [ "$BASE_VERSION" != "$HEAD_VERSION" ]; then VERSION_CHANGED=true echo "Version change detected in $FILE" fi fi done if [ "$VERSION_CHANGED" = true ]; then echo "Manual version changes are prohibited. Use changesets instead." exit 1 fi env: GITHUB_REF: ${{ github.ref }} Popri tejto kontrole úloha inštaluje závislosti, overuje obmedzenia, kontroluje kruhové závislosti a overuje celkovú kvalitu kódu pomocou skriptu, ktorý sme predtým definovali v NX: check-quality - id: install-dependencies name: Install dependencies run: yarn --immutable - id: check-constraints name: Check constraints run: yarn constraints - id: check-circulardeps name: Check circular dependencies run: yarn check-circulardeps:all - id: check-quality name: Check quality run: BASE=origin/${{ github.event.pull_request.base.ref }} yarn quality:affected Kontrola kvality je navrhnutá tak, aby sa spustila iba na balíkoch ovplyvnených aktuálnou požiadavkou na stiahnutie. Úspešné dokončenie týchto úloh signalizuje, že požiadavka na stiahnutie je pripravená na zlúčenie (okrem prijatia kontroly kódu). Ak sú pre váš projekt potrebné ďalšie kontroly, môžete aktualizovať svoj a skript kvality, pričom pracovný postup zostane nezmenený. nx.json Publikovanie knižníc a funkcií Po zlúčení PR sa spustí pracovný postup vydania (ako je popísané v kapitole Sady zmien). Tento pracovný postup vytvára ovplyvnené balíky a vytvára PR so zmenami verzií. Po schválení a zlúčení tohto PR sa znova spustí – tentoraz namiesto vytvorenia PR zisťuje zmeny verzie a uvoľňuje aktualizované balíčky do NPM: release.yaml - id: build-packages name: Build packages run: yarn build:affected - id: create-release-pull-request-or-publish name: Create Release Pull Request or Publish to NPM uses: changesets/action@v1 with: version: yarn changeset version publish: yarn release commit: "chore: publish new release" title: "chore: publish new release" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} release-apps: needs: release-libs-features uses: ./.github/workflows/release-apps.yaml with: publishedPackages: ${{ needs.release-libs-features.outputs.publishedPackages }} Potom sa vykoná úloha s názvom , ktorá je zodpovedná za nasadenie aplikácií. Prijíma zoznam publikovaných balíkov z predchádzajúceho kroku a privádza nás k ďalšej kapitole. release-apps Publikovanie aplikácií Posledná časť procesu vydania zahŕňa nasadenie vašich aplikácií (aplikácie nie sú publikované v NPM, pretože sú nastavené v ). Pracovný postup sa automaticky spúšťa súborom alebo ho možno spustiť priamo z karty Akcie na GitHub: private package.json release-apps.yaml release.yaml name: Release Apps on: workflow_call: inputs: publishedPackages: description: "List of published packages" required: false type: string default: "[]" workflow_dispatch: inputs: publishedPackages: description: "List of published packages (optional)" required: false type: string default: "[]" Tento pracovný postup akceptuje vstup na určenie, ktoré balíky boli publikované. Pomocou maticovej stratégie kontroluje každú aplikáciu matice na prítomnosť publikovaných závislostí: publishedPackages - id: check-dependency-published name: Check if any app dependency is published run: | PUBLISHED_PACKAGES="${{ inputs.publishedPackages }}" PACKAGE_NAME="${{ matrix.package }}" APP="${{ matrix.app }}" DEPENDENCIES=$(jq -r '.dependencies // {} | keys[]' "apps/$APP/package.json") for DEP in $DEPENDENCIES; do if echo "$PUBLISHED_PACKAGES" | grep -w "$DEP"; then echo "published=true" >> $GITHUB_OUTPUT exit 0 fi done echo "published=false" >> $GITHUB_OUTPUT Táto kontrola je jednou z podmienok na spustenie nasadenia aplikácie. Druhá podmienka zaisťuje, že sa zmenila verzia aplikácie (čo naznačuje, že je potrebné opätovné nasadenie, aj keď neboli aktualizované žiadne závislosti): - id: check-version-change name: Check if app version has changed run: | APP="${{ matrix.app }}" PACKAGE_JSON_PATH="apps/$APP/package.json" CURRENT_VERSION=$(jq -r '.version' "$PACKAGE_JSON_PATH") PREVIOUS_VERSION=$(git show HEAD~1:"$PACKAGE_JSON_PATH" | jq -r '.version' || echo "") if [[ "$CURRENT_VERSION" == "$PREVIOUS_VERSION" ]]; then echo "changed=false" >> $GITHUB_OUTPUT else echo "changed=true" >> $GITHUB_OUTPUT fi Nakoniec, po potvrdení, že aplikácia má aktualizované závislosti alebo sa jej verzia zmenila, pracovný postup načíta novú verziu a pokračuje v zostavovaní a nasadzovaní aplikácie: - id: set-up-docker name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - id: get-app-version name: Get the app version from package.json run: echo "app-version=$(cat ./apps/${{ matrix.app }}/package.json | jq -r '.version')" >> $GITHUB_OUTPUT - id: build-image name: Build image if: steps.check-dependency-published.outputs.published == 'true' || steps.check-version-change.outputs.changed == 'true' uses: docker/build-push-action@v4 with: build-contexts: | workspace=./ context: "./apps/${{ matrix.app }}" load: true push: false tags: | ${{ matrix.app }}:v${{ steps.get-app-version.outputs.app-version }} V tomto príklade vytvárame obraz Docker bez toho, aby sme ho vložili do registra. Vo svojom produkčnom pracovnom postupe nahraďte tento krok skutočným procesom nasadenia. Záver Rekapitulácia osvedčených postupov V tomto článku sme preskúmali nastavenie robustného monorepa a nástroje, ktoré ho pomáhajú efektívne spravovať. Centralizáciou vašej kódovej základne nielen zjednodušíte správu závislostí, ale aj zefektívnite spoluprácu medzi tímami. Ukázali sme, ako možno Yarn využiť na zdieľanie závislostí, zrýchlenie inštalácie s PnP a zlepšenie celkovej konzistencie projektu. Integrácia NX pre cielené vykonávanie skriptov navyše zaisťuje, že CI je rýchle a efektívne. Sady zmien pomohli zautomatizovať vytváranie verzií, znížiť manuálne chyby a zjednodušiť vydania. Nakoniec sme vytvorili produkčný kanál CI/CD s akciami GitHub, ktorý vykonáva iba nevyhnutné úlohy. Ďalšie kroky : Začnite nastavením malého monorepo na testovanie týchto osvedčených postupov. Experimentujte s rôznymi štruktúrami priečinkov a postupne ich rozbaľte tak, aby obsahovali viac balíkov, keď vaše sebavedomie rastie. Experimentujte a prispôsobte sa : Zvážte integráciu doplnkových nástrojov, ako sú PNPM alebo Turborepo, na základe jedinečných požiadaviek vášho projektu a preferencií tímu. Integrujte ďalšie nástroje : Dolaďte svoje pracovné postupy GitHub Actions tak, aby zahŕňali dodatočné kontroly kvality, pokrytie kódu a bezpečnostné skeny prispôsobené vášmu projektu. Vylepšite kanály CI/CD : Zostaňte informovaní o najnovších vydaniach Yarn, NX a Changesets. Zapojte sa do komunity, aby ste sa podelili o poznatky a dozvedeli sa o nových trendoch v správe monorepo. Komunita a aktualizácie Zdroje : Príklad úložiska Získajte prístup ku kompletnému vzorovému úložisku vytvorenému pre túto príručku. Preskúmajte štruktúru projektu, ukážky kódu a skripty, ktoré predvádzajú nastavenie monorepo v akcii. : Zverejnené balíčky NPM Pozrite si aktuálny balík NPM publikovaný ako súčasť tohto projektu. Tieto balíky demonštrujú reálne využitie a implementáciu konceptov diskutovaných v tomto článku.