Johdanto Miksi Monorepo? Nykyään ohjelmistokehityksen nopeaa kehitystä ei voida kiistää. Tiimit kasvavat, projektit ovat yleensä monimutkaisempia. Yritykset käyttävät huomattavia resursseja ylläpitääkseen hajautettua koodikantaa, joka koostuu monista fragmenteista. Anna monorepo - yksi yhtenäinen arkisto, joka kokoaa yhteen kaikki koodisi. Monoreposista on suinkaan tullut trendi, vaan niistä on viime aikoina tullut arkkitehtoninen tapa sijoittaa koko koodikanta yhteen paikkaan. Tiimit saavat parannetun kontekstin jakamisen, sujuvan yhteistyön ja työkalun, joka luonnollisesti kannustaa koodin uudelleenkäyttöön. Lankatyötilojen asettaminen Huomautus: Aina kun tässä artikkelissa mainitaan "lanka", se viittaa erityisesti Yarn v4:ään – uusimpaan versioon, joka tarjoaa parannettuja ominaisuuksia ja parannetun suorituskyvyn. Mitä lankatyötilat ovat? Työtilat ovat monorepon paketteja, joita usein kutsutaan paketeiksi. Niiden avulla voit hallita useita paketteja yhdessä arkistossa vaivattomasti. Työtiloilla. voit: Jaa riippuvuuksia helposti: Jaa yhteiset riippuvuudet projektissasi saumattomasti. Yksinkertaista riippuvuuden hallinta: Lanka linkittää automaattisesti paikalliset paketit, mikä vähentää päällekkäisyyksiä ja helpottaa kehitystä. Asennusten nopeuttaminen: Hyödynnä Yarnin suorituskyvyn optimointia ja välimuistimekanismeja (eli ). sisäänrakennettu plug'n'play Paranna Monorepon hallintaa: Määritä (säännöt) ja käytä johdonmukaisuuden ylläpitämiseksi. rajoitukset kymmeniä saatavilla olevia laajennuksia Vaikka Yarn on valittu tämän artikkelin johtaja yksinkertaisuuden, nopeuden ja laajojen konfigurointivaihtoehtojensa ansiosta, on tärkeää huomata, että oikea valinta riippuu projektisi erityistarpeista, tiimin mieltymyksistä ja yleisestä työnkulusta. Esimerkiksi ja ovat muita moderneja työkaluja, jotka tarjoavat laajan valikoiman ominaisuuksia. PNPM Turborepo Alkukokoonpano Langan asennus on suoraviivainen prosessi. Noudata virallista opasta asentaaksesi ja määrittääksesi langan projektiisi: . Lanka-asennusopas Kun olet suorittanut asennuksen, siirrytään konfigurointiin. Koska käytämme plug'n'play-toimintoa, sinun on varmistettava, että IDE tunnistaa riippuvuudet oikein. Jos käytät VSCodea, suorita: # Typescript is required for VSCode SDK to set up correctly yarn add -D typescript@^5 yarn dlx @yarnpkg/sdks vscode Jos käytät toista koodieditoria, tarkista saatavilla olevat SDK:t täältä: . Lankaeditorin SDK:t Tässä vaiheessa olet valmis aloittamaan langan käytön. Monorepo-rakenteen järjestäminen Nyt kun paketinhallinta on määritetty, on aika suunnitella skaalautuva projektiorganisaatio. Selkeä, hyvin määritelty rakenne paitsi helpottaa arkiston navigointia, myös edistää parempaa koodin uudelleenkäyttöä. Tässä esimerkissä jaamme koodikannan kolmeen pääluokkaan: : Sovellukset Asiakas: Sisältää lopulliset, käyttöön otettavat asiakastuotteet. Palvelin: Sisältää lopulliset, käyttöön otettavat palvelintuotteet. : Ominaisuudet Asiakas: erillisille käyttöliittymäwidgeteille. Palvelin: Itsenäisille taustajärjestelmän liikelogiikkaosille. : Libs Talot jaetut koodit, kuten suunnittelujärjestelmän komponentit, vakiot, resurssit ja apuohjelmat. Tämä on kontekstiton vyöhyke uudelleenkäytettävän logiikan tallentamiseen. Osoittaaksesi tämän kansiorakenteen tehon, aloitetaan lisäämällä nämä tärkeimmät kansiot Yarnin työtilaluetteloon. Lisää root package.json -tiedostoon seuraava: "workspaces": [ "apps/**", "features/**", "libs/**" ] Tämä kokoonpano käskee Yarnin käsittelemään näissä kansioissa olevia paketteja paikallisina paketteina. Myöhemmät asennukset varmistavat, että kunkin paketin riippuvuudet on määritetty ja linkitetty oikein. Bootstrapping Codebase Tässä osiossa käymme läpi minimaalisen koodikannan esimerkin, joka havainnollistaa monorepon käynnistämistä. Sen sijaan, että sisällyttäisin täydelliset koodinpätkät, annan lyhyitä esimerkkejä linkkien kanssa tiedostoihin. erityisesti tätä artikkelia varten luodun arkiston Bootstrapping-palvelinsovellus Aloitamme yksinkertaisella käyttäjän todennusta varten. Tämä palvelinsovellus paljastaa yhden päätepisteen ( ), joka käyttää toisen paketin käsittelijää. Express API:lla /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}`); }); Linkki pakettiin Kuten näet, -päätepiste käyttää käsittelijää, joka on tuotu toisesta paketista. Tästä pääsemme seuraavaan komponenttiin: palvelinominaisuuteen. /auth/signIn Bootstrapping Server -ominaisuus Palvelinominaisuus kapseloi todennuslogiikan. Tässä paketissa määritämme kirjautumiskäsittelijän, joka hyödyntää libsien jaettua vahvistusapuohjelmaa. 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; Linkki pakettiin Tämä lähestymistapa tiivistää todennuslogiikan omassa paketissaan, mikä mahdollistaa sen kehittämisen ja ylläpidon itsenäisesti. Huomaa, kuinka validointiapuohjelmat tuodaan . jaetusta libistä Bootstrapping-asiakassovellus Katsotaan seuraavaksi asiakaspuolta. Asiakassovelluksessamme rakennamme yksinkertaisen verkkosivuston, joka mahdollistaa käyttäjän todennuksen palvelimen API:n avulla. "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> ); } Linkki pakettiin Tässä esimerkissä komponentti tuodaan asiakkaan ominaisuuspaketista, joka johtaa meidät lopulliseen komponenttiimme. SignInForm Bootstrapping Client -ominaisuus Asiakasominaisuuspaketti tarjoaa todennuslomakkeen ja jaetun vahvistuslogiikan. Tämä välttää koodin päällekkäisyyden ja varmistaa johdonmukaisuuden. 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; Linkki pakettiin Täällä näemme jälleen käytön jaetuista libistämme, mikä varmistaa, että validointilogiikka on keskitetty ja helposti ylläpidettävä. validaattorin Siinä se minimaalisen koodikannan esimerkissämme. Muista, että tämä koodi on yksinkertaistettu kuva, jonka tarkoituksena on havainnollistaa sovellusten, ominaisuuksien ja lisenssien perusrakennetta ja keskinäistä yhteyttä monorepossa. Voit laajentaa näitä esimerkkejä tarpeen mukaan vastaamaan projektisi erityisvaatimuksia. Skriptien suorittaminen NX:n kanssa Skriptien hallinta monorepossa voi olla haastavaa. Vaikka Yarnin avulla voit eri ehdoilla, se voi vaatia mukautettuja komentosarjoja tarkemman hallinnan saamiseksi. Tässä NX tulee esiin: se tarjoaa käyttövalmiin ratkaisun tehokkaaseen ja kohdistettuun komentosarjan suorittamiseen. ajaa skriptejä useissa paketeissa NX:n esittely NX on koontijärjestelmä, joka on optimoitu monoreposille edistyneillä CI-ominaisuuksilla. NX:n avulla voit: : Hyödynnä samanaikaisuutta nopeuttaaksesi rakentamistasi. Suorita tehtäviä tehokkaasti rinnakkain : Ymmärrä pakettien ja komentosarjojen väliset yhteydet. Tunnista riippuvuussuhteet : Vältä ylimääräinen työ tallentamalla tulosteet välimuistiin. Välimuistin komentosarjan suoritustulokset Laajenna toimintoja avulla. Mukauta toimintaa laajennuksilla: runsaan laajennusekosysteemin Kohdennettu komentosarjan suoritus Hyödyntääksemme NX:n ominaisuuksia meidän on ensin luotava -tiedosto, joka määrittää komentosarjoillemme säännöt. Alla on esimerkki kokoonpanosta: nx.json { "targetDefaults": { "build": { "dependsOn": [ "^build" ], "outputs": [ "{projectRoot}/dist" ], "cache": true }, "typecheck": { "dependsOn": [ "^build", "^typecheck" ] }, "lint": { "dependsOn": [ "^build", "^lint" ] } }, "defaultBase": "main" } Selkeällä englanniksi tämä kokoonpano tarkoittaa: Rakentaa Paketin riippuu sen riippuvuuksien onnistumisesta, ja sen tulos on välimuistissa. build Typecheck Paketin riippuu sekä sen riippuvuuksien koonti- että tyyppitarkistuskomentosarjasta. typecheck Nukka Paketin -skripti riippuu sekä sen riippuvuuksien koonti- että lint-skripteistä. lint Lisätään nyt komentosarjat tiedostoon: 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}" } Tässä määrittelemme neljä suoritusskriptityyppiä: rakentaa paketin. rakentaa: Tarkistaa paketin tyypit. typecheck: Nukkaa paketin. nukkaa: Suorittaa sekä tyyppitarkistuksen että nukkauksen. laatu: Jokaisella skriptillä on kaksi muunnelmaa: Suorittaa komentosarjan kaikissa paketeissa. all: Suorittaa komentosarjan vain paketeissa, joihin viimeaikaiset muutokset vaikuttavat. ja -ympäristömuuttujien avulla voit määrittää alueen (oletuksena ja nykyinen ), mikä mahdollistaa raellisen suorituksen vetopyynnöissä. Tämä voi säästää huomattavasti aikaa ja resursseja. vaikuttaa: BASE HEAD origin/main HEAD Pyöreän riippuvuuden hallinta NX tarjoaa myös riippuvuuskaavion luomiseksi, mikä voi auttaa riippuvuusjaksojen havaitsemisessa. Seuraava komentosarja käyttää NX-kuvaajan lähtöä tarkistaakseen pyöreät riippuvuudet ja epäonnistuu, jos sellaisia löytyy. sisäänrakennetun komennon Luo tiedosto osoitteessa jossa on seuraava sisältö: 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(); Tämä skripti: Suorittaa NX-komennon luodakseen riippuvuuskaavion. Lukee kaavion väliaikaisesta JSON-tiedostosta. Tarkistaa syklit rekursiivisesti. Kirjaa virheen ja poistuu, jos havaitaan pyöreä riippuvuus. Riippuvuuksien vahvistaminen lankarajoituksilla Projektien kasvaessa riippuvuussuhteiden johdonmukaisuuden ylläpitämisestä tulee haastavaa. Riippuvuuksia, solmuversioita ja muita kokoonpanoja koskevien tiukkojen sääntöjen noudattaminen on välttämätöntä tarpeettoman teknisen velan välttämiseksi. Lankarajoitukset tarjoavat tavan automatisoida nämä tarkistukset. Lankarajoitusten ymmärtäminen Lankarajoitukset ovat monorepon pakettien sääntöjä. Niiden käytön merkittävä etu on, että olet näiden sääntöjen ylläpitäjä. Voit esimerkiksi luoda säännön pakottaaksesi kaikki paketit käyttämään samaa React-versiota. Kun se on asetettu, et koskaan törmää ongelmaan, jos isäntäsovellus ei voi käyttää ominaisuutta/libiä korkeammalla React-versiolla. Vaikka suuren monorepon siirtäminen uuteen pääversioon riippuvuudesta voi olla monimutkaista, rajoitusten käyttö tuo lopulta johdonmukaisuutta ja vakautta koko projektiin. Johdonmukaisuuden varmistaminen Esimerkkivarastossamme käytämme -tiedostoa johdonmukaisuuden varmistamiseen: yarn.config.cjs Solmun versio Lanka versio Riippuvuuksien versiot Joustavuuden lisäämiseksi siirtymien aikana voit määrittää poissulkemisia ohittaaksesi väliaikaisesti tietyt tarkistukset. Esimerkiksi: const workspaceCheckExclusions = []; const dependencyCheckExclusions = []; Näiden vakioiden avulla voit sulkea tiettyjä työtiloja tai riippuvuuksia validointiprosessista, mikä varmistaa sujuvan siirron tarvittaessa. Versioinnin hallinta muutosjoukkojen avulla Toinen ongelma, jonka saatat kohdata arkiston kasvun yhteydessä, on versionhallinta ja julkaisu. Muutossarjat tarjoavat tyylikkään ratkaisun tämän prosessin automatisoimiseen ja varmistavat, että jokaista muutosta seurataan, versioidaan ja julkaistaan. Johdanto Changesetsiin on avoimen lähdekoodin työkalu, joka on suunniteltu hallitsemaan versiointia monorepo-tietovarastoissa. Se yksinkertaistaa muutosten seurantaa jakamalla ne pieniin, ihmisen luettavissa oleviin asiakirjoihin, jotka kuvaavat muutoksen tarkoituksen. Näitä asiakirjoja kutsutaan muutosjoukoiksi. Keskeisiä etuja ovat: Changesets Selkeä dokumentaatio Jokainen muutossarja hahmottelee tehdyt muutokset, mikä auttaa sekä kehittäjiä että kuluttajia ymmärtämään, mitä uutta julkaisua odottaa. Rakeinen versionhallinta Jokainen paketti versioitetaan itsenäisesti, mikä varmistaa, että vain kyseiset paketit päivitetään. Tämä minimoi tyhjien versiovirheiden ja riippuvuuskatkojen riskin. Yhteistyöystävällinen Koska jokainen muutos tallennetaan muutossarjan kautta, tiimit voivat tarkistaa ja hyväksyä päivitykset ennen varsinaista julkaisua. Julkaisujen automatisointi Yksi Changesetsin tehokkaimmista ominaisuuksista on kyky automatisoida prosessi. Voit integroida muutossarjat CI/CD-putkeen ja unohtaa manuaaliset versiomuutokset ja NPM-julkaisut. Katso -työnkulku esimerkkiarkistosta. Siinä on vaihe. Vaihe, jota tukee GitHub-toiminto luo kaiken taian. Sinun tarvitsee vain määrittää pakettien julkaisemista varten. Sitten jokainen työntö : release.yaml create-release-pull-request-or-publish Changesets/action NPM_TOKEN main . Tarkista, onko Changeset-asiakirjoja Jos muutosjoukkoasiakirjoja on, toiminto luo vetopyynnön, joka sisältää tarvittavat versiovirheet ja muutoslokipäivitykset. Jos muutoksia ei havaita, mitään ei tapahdu. . Tarkista, onko julkaisuvalmiita paketteja Jos paketit ovat valmiita julkaistavaksi, toiminto julkaisee uudet versiot NPM:lle käyttämällä annettua . Jos julkaisuvalmiita paketteja ei ole, toiminto poistuu tekemättä muutoksia. NPM_TOKEN Automatisoimalla nämä tehtävät Changesets varmistaa, että julkaisusi ovat johdonmukaisia ja luotettavia, mikä vähentää inhimillisten virheiden mahdollisuutta ja virtaviivaistaa kehitystyönkulkua. Työnkulun integrointi GitHub Actionsin kanssa Tässä osiossa tarkastellaan, kuinka juuri rakentamamme arkkitehtuurin voima saadaan valloilleen. GitHub Actionsin avulla automatisoimme PR-laadun tarkistukset, kirjastojen ja ominaisuuksien versiojulkaisut sekä sovellusten käyttöönotot. Painopiste on automatisoinnin maksimoinnissa ja samalla koodin laadun ja työn tarkkuuden säilyttämisessä. Tarkista PR-laatu Varmistaaksemme, että vetopyyntökoodi pysyy yhtenäisenä ja vakaana, luomme oman -työnkulun. Tämä työnkulku suorittaa useita tehtäviä, kuten varmistaa, että manuaalisia versiomuutoksia ei tehdä (koska versiointia hallinnoi Changesets): 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 }} Tämän tarkistuksen ohella asentaa riippuvuuksia, vahvistaa rajoitukset, tarkistaa kiertoriippuvuudet ja varmistaa koodin yleisen laadun käyttämällä komentosarjaa, jonka määritimme aiemmin NX:n kanssa: 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 Laaduntarkistus on suunniteltu suoritettavaksi vain paketeissa, joihin nykyinen vetopyyntö vaikuttaa. Näiden töiden onnistunut suorittaminen merkitsee, että vetopyyntö on valmis yhdistämään (kooditarkistusten vastaanottamisen lisäksi). Jos projekti vaatii lisätarkastuksia, voit päivittää tiedostosi ja laatukomentosarjasi pitämällä työnkulun ennallaan. nx.json Julkaise kirjastoja ja ominaisuuksia Kun PR on yhdistetty, julkaisutyönkulku (kuten on kuvattu Muutossarjat-luvussa) käynnistyy. Tämä työnkulku rakentaa ongelmalliset paketit ja luo PR:n versiovirheillä. Kun tämä PR on hyväksytty ja yhdistetty, suoritetaan uudelleen – tällä kertaa PR:n luomisen sijaan se havaitsee versiomuutokset ja julkaisee päivitetyt paketit NPM:lle: 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 }} Tämän jälkeen suoritetaan työ nimeltä , joka vastaa sovellusten käyttöönotoista. Se vastaanottaa luettelon edellisen vaiheen julkaistuista paketeista ja vie meidät seuraavaan lukuun. release-apps Julkaise sovelluksia Julkaisuprosessin viimeinen osa sisältää sovellusten käyttöönoton (sovelluksia ei julkaista NPM:lle, koska ne on asetettu paketissa ). työnkulun käynnistää automaattisesti , tai se voidaan suorittaa suoraan GitHubin Toiminnot-välilehdeltä: 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: "[]" Tämä työnkulku hyväksyy paketit määrittämään julkaistut paketit. Matriisistrategian avulla se tarkistaa matriisin jokaisesta sovelluksesta julkaistujen riippuvuuksien olemassaolon: 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ämä tarkistus on yksi ehto sovelluksen käyttöönoton aloittamiselle. Toinen ehto varmistaa, että sovelluksen versiota on muutettu (osoittaa, että uudelleenjärjestely on tarpeen, vaikka riippuvuuksia ei olisi päivitetty): - 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 Lopuksi, kun on vahvistettu, että sovelluksella on joko päivitettyjä riippuvuuksia tai sen versio on muuttunut, työnkulku hakee uuden version ja jatkaa sovelluksen rakentamista ja käyttöönottoa: - 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 }} Tässä esimerkissä luomme Docker-kuvan työntämättä sitä rekisteriin. Korvaa tämä vaihe tuotantotyönkulussasi varsinaisella käyttöönottoprosessilla. Johtopäätös Yhteenveto parhaista käytännöistä Tämän artikkelin aikana tutkimme vankan monorepon käyttöönottoa ja työkaluja, jotka auttavat hallitsemaan sitä tehokkaasti. Keskittämällä kooditietokantasi et vain yksinkertaista riippuvuuden hallintaa, vaan myös virtaviivaistat tiimien välistä yhteistyötä. Osoitimme, kuinka Lankaa voidaan hyödyntää jakamaan riippuvuuksia, nopeuttamaan asennusta PnP:n avulla ja parantamaan projektin yleistä johdonmukaisuutta. Lisäksi NX:n integrointi kohdennettuun komentosarjan suorittamiseen varmistaa, että CI on nopea ja tehokas. Muutossarjat auttoivat automatisoimaan versiointia, vähentämään manuaalisia virheitä ja virtaviivaistamaan julkaisuja. Lopuksi olemme tehneet tuotantovalmiin CI/CD-putkilinjan GitHub-toiminnoilla, joka suorittaa vain tarvittavat tehtävät. Seuraavat vaiheet : Aloita perustamalla pienimuotoinen monorepo testataksesi näitä parhaita käytäntöjä. Kokeile erilaisia kansiorakenteita ja laajenna asteittain lisäämään paketteja itseluottamuksesi kasvaessa. Kokeile ja mukauta : Harkitse täydentävien työkalujen, kuten PNPM:n tai Turborepon, integrointia projektisi ainutlaatuisten vaatimusten ja tiimin mieltymysten perusteella. Integroi lisätyökaluja : Hienosäädä GitHub Actions -työnkulkujasi lisäämällä laatutarkistuksia, koodin kattavuutta ja projektiisi räätälöityjä suojaustarkistuksia. Paranna CI/CD-putkistoja : Pysy ajan tasalla Yarnin, NX:n ja Changesetsin uusimmista julkaisuista. Ota yhteyttä yhteisön kanssa jakaaksesi oivalluksia ja oppiaksesi monorepo-hallinnan nousevista trendeistä. Yhteisö ja päivitykset Resurssit : Esimerkkivarasto Käytä tätä opasta varten luotua täydellistä esimerkkivarastoa. Tutustu projektin rakenteeseen, koodinäytteisiin ja komentosarjoihin, jotka esittelevät monorepo-kokoonpanon toiminnassa. : Julkaistut NPM-paketit Tutustu varsinaiseen NPM-pakettiin, joka on julkaistu osana tätä projektia. Nämä paketit havainnollistavat artikkelissa käsiteltyjen käsitteiden todellista käyttöä ja toteutusta.