Utangulizi Kwa nini Monorepo? Siku hizi, mageuzi ya haraka ya maendeleo ya programu hayawezi kukataliwa. Timu zinakua, miradi huwa ngumu zaidi. Makampuni hutumia rasilimali nyingi kudumisha codebase iliyosambazwa inayojumuisha vipande vingi. Ingiza monorepo - hazina moja, iliyounganishwa ambayo huleta pamoja msimbo wako wote. Mbali na kuwa mtindo, monorepos hivi karibuni imekuwa mbinu ya usanifu wa kuweka msingi wote wa kanuni katika sehemu moja. Timu hupata ushirikishwaji ulioboreshwa wa muktadha, ushirikiano mzuri na zana ambayo inahimiza utumiaji wa msimbo tena. Kuweka Nafasi za Kazi za Uzi Kumbuka: Katika makala haya yote, wakati wowote "Uzi" inapotajwa, inarejelea Uzi v4—toleo la hivi punde linalotoa uwezo ulioimarishwa na utendakazi ulioboreshwa. Nafasi za kazi za Uzi ni nini? Nafasi za kazi ni vifurushi vya monorepo, mara nyingi huitwa vifurushi. Wanakusaidia kudhibiti vifurushi vingi kwenye hazina moja bila bidii. Pamoja na maeneo ya kazi. unaweza: Shiriki Vitegemezi kwa Urahisi: Shiriki vitegemezi vya kawaida kwenye mradi wako bila mshono. Rahisisha Usimamizi wa Utegemezi: Uzi huunganisha kiotomatiki vifurushi vya ndani, kupunguza marudio na kurahisisha maendeleo. Ongeza kasi ya Usakinishaji: Faidika na uboreshaji wa utendakazi wa Yarn na mifumo ya kuweka akiba (yaani, ). iliyojengewa ndani plug'n'play Boresha Udhibiti wa Monorepo: Bainisha (sheria) na utumie ili kudumisha uthabiti. vikwazo programu-jalizi kadhaa zinazopatikana Ingawa Uzi ndiye msimamizi aliyechaguliwa wa makala haya kutokana na usahili wake, kasi, na chaguo pana za usanidi - ni muhimu kutambua kwamba chaguo sahihi inategemea mahitaji mahususi ya mradi wako, mapendeleo ya timu na mtiririko wa kazi kwa ujumla. Kwa mfano, na ni zana zingine za kisasa ambazo hutoa anuwai ya vipengele. PNPM Turborepo Usanidi wa Awali Kuweka uzi ni mchakato wa moja kwa moja. Fuata mwongozo rasmi ili kusakinisha na kusanidi Uzi katika mradi wako: . Mwongozo wa Ufungaji wa Uzi Mara tu unapokamilisha usakinishaji, wacha tuendelee kwenye usanidi. Kwa kuwa tunatumia plug'n'play, unahitaji kuhakikisha kuwa IDE yako inatambua vitegemezi kwa usahihi. Ikiwa unatumia VSCode, endesha: # Typescript is required for VSCode SDK to set up correctly yarn add -D typescript@^5 yarn dlx @yarnpkg/sdks vscode Ikiwa unatumia kihariri kingine cha msimbo, angalia SDK zinazopatikana hapa: . SDK za Uhariri wa Vitambaa Kwa hatua hii, mko tayari kuanza kutumia Uzi. Kuandaa Muundo wa Monorepo Sasa kwa kuwa kidhibiti kifurushi kimesanidiwa, ni wakati wa kubuni shirika la mradi ambalo linaweza kupunguzwa. Muundo ulio wazi na uliobainishwa vyema sio tu kwamba hurahisisha uelekezaji wa hazina bali pia unakuza matumizi bora ya msimbo. Katika mfano huu, tutagawanya msingi wa kanuni katika kategoria tatu kuu: : Programu Mteja: Ina bidhaa za mwisho za mteja zinazoweza kutumika. Seva: Ina bidhaa za seva za mwisho, zinazoweza kutumiwa. : Vipengele Mteja: Kwa wijeti za UI zinazojitegemea. Seva: Kwa vipande vya mantiki ya biashara inayojitegemea. : Libs Msimbo wa nyumba unaoshirikiwa kama vile vipengee vya mfumo wa kubuni, vipengee, mali na huduma. Hili ndilo eneo lisilo na muktadha la kuhifadhi mantiki inayoweza kutumika tena. Ili kuonyesha uwezo wa muundo wa folda hii, hebu tuanze kwa kuongeza folda hizi kuu kwenye orodha ya nafasi za kazi za Uzi. Katika root package.json yako, ongeza yafuatayo: "workspaces": [ "apps/**", "features/**", "libs/**" ] Usanidi huu unaambia Uzi kutibu vifurushi kwenye folda hizi kama vifurushi vya ndani. Usakinishaji unaofuata utahakikisha kuwa vitegemezi vya kila kifurushi vimewekwa na kuunganishwa ipasavyo. Bootstrapping Codebase Katika sehemu hii, tutapitia mfano mdogo wa codebase ambao unaonyesha jinsi ya bootstrap monorepo. Badala ya kujumuisha vijisehemu kamili vya msimbo, nitatoa mifano mifupi iliyo na viungo vya faili kamili kwenye . hazina iliyoundwa mahususi kwa makala haya Maombi ya Seva ya Bootstrapping Tunaanza na kwa uthibitishaji wa mtumiaji. Programu hii ya seva inafichua ncha moja ( ) ambayo hutumia kidhibiti kutoka kwa kifurushi kingine. API rahisi ya Express /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}`); }); Unganisha kwa kifurushi Kama unavyoona, mwisho wa hutumia kidhibiti kilichoingizwa kutoka kwa kifurushi kingine. Hiyo inatuleta kwenye sehemu yetu inayofuata: kipengele cha seva. /auth/signIn Kipengele cha Seva ya Bootstrapping Kipengele cha seva kinajumuisha mantiki ya uthibitishaji. Katika kifurushi hiki, tunafafanua kidhibiti cha kuingia, ambacho hutumia matumizi ya uthibitishaji yaliyoshirikiwa kutoka kwa libs. 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; Unganisha kwa kifurushi Mbinu hii ni muhtasari wa mantiki ya uthibitishaji ndani ya kifurushi chake, ikiruhusu kuendelezwa na kudumishwa kwa kujitegemea. Tazama jinsi huduma za uthibitishaji huletwa kutoka kwa . lib iliyoshirikiwa Programu ya Mteja wa Kufunga Mtambo Ifuatayo, wacha tuangalie upande wa mteja. Katika programu yetu ya mteja, tunaunda tovuti rahisi ambayo huwezesha uthibitishaji wa mtumiaji kwa kutumia API ya seva. "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> ); } Unganisha kwa kifurushi Katika mfano huu, kipengele cha kinaletwa kutoka kwa kifurushi cha kipengele cha mteja, ambacho hutupeleka kwenye kipengee chetu cha mwisho. SignInForm Kipengele cha Mteja cha Kufunga Mtambo Kifurushi cha kipengele cha mteja hutoa fomu ya uthibitishaji pamoja na mantiki ya uthibitishaji iliyoshirikiwa. Hii inaepuka kunakili msimbo na inahakikisha uthabiti. 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; Unganisha kwa kifurushi Hapa, tunaona tena matumizi ya kutoka kwa libs zetu zilizoshirikiwa, kuhakikisha kuwa mantiki ya uthibitishaji iko katikati na kudumishwa kwa urahisi. kiidhinishi Hiyo ni kwa mfano wetu mdogo wa codebase. Kumbuka kwamba msimbo huu ni kielelezo kilichorahisishwa kinachokusudiwa kuonyesha muundo msingi na muunganisho kati ya Programu, Vipengee na Libs katika monorepo. Unaweza kupanua mifano hii inapohitajika ili kuendana na mahitaji mahususi ya mradi wako. Inaendesha Hati na NX Kusimamia hati katika monorepo kunaweza kuwa changamoto. Ingawa Uzi hukuruhusu kwa kutumia hali mbalimbali, inaweza kuhitaji uandishi maalum kwa udhibiti wa punjepunje. Hapa ndipo NX inapoingia: hutoa suluhu ya nje ya kisanduku kwa utekelezaji mzuri wa hati unaolengwa. kuendesha hati kwenye vifurushi vingi Utangulizi wa NX NX ni mfumo wa kujenga ulioboreshwa kwa monorepos na uwezo wa juu wa CI. Ukiwa na NX, unaweza: : Tumia upatanishi ili kuharakisha ujenzi wako. Endesha kazi kwa ufanisi sambamba : Elewa miunganisho kati ya vifurushi na hati. Tambua uhusiano wa utegemezi : Epuka kazi isiyo ya lazima kwa kuakibisha matokeo. Matokeo ya utekelezaji wa hati ya akiba Panua utendakazi kupitia . Geuza tabia ukitumia programu-jalizi kukufaa: mfumo tajiri wa ikolojia wa programu-jalizi Utekelezaji wa Hati Uliolengwa Ili kutumia uwezo wa NX, tunahitaji kwanza kuunda faili ya ili kufafanua seti ya sheria za hati zetu. Chini ni mfano wa usanidi: nx.json { "targetDefaults": { "build": { "dependsOn": [ "^build" ], "outputs": [ "{projectRoot}/dist" ], "cache": true }, "typecheck": { "dependsOn": [ "^build", "^typecheck" ] }, "lint": { "dependsOn": [ "^build", "^lint" ] } }, "defaultBase": "main" } Kwa Kiingereza wazi, usanidi huu unamaanisha: Jenga Nakala ya wa kifurushi inategemea ujenzi uliofanikiwa wa utegemezi wake, na matokeo yake yamehifadhiwa. build Aina ya ukaguzi Nakala ya kifurushi inategemea maandishi ya muundo na chapa ya utegemezi wake. typecheck Lint Hati ya kifurushi inategemea maandishi ya ujenzi na laini ya utegemezi wake. lint Sasa, wacha tuongeze maandishi kwenye : 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}" } Hapa, tunafafanua aina nne za hati za utekelezaji: Hujenga kifurushi. kujenga: Huangalia aina za kifurushi. typecheck: Huweka kifurushi. lint: Huendesha kikagua chapa na pamba.' ubora: Kila hati ina tofauti mbili: Huendesha hati kwenye vifurushi vyote. zote: Huendesha hati kwenye vifurushi vilivyoathiriwa na mabadiliko ya hivi majuzi pekee. Vigezo vya mazingira ya na hukuruhusu kubainisha masafa (chaguo-msingi hadi na ya sasa ), kuwezesha utekelezaji wa punjepunje kwenye maombi ya kuvuta. Hii inaweza kuokoa muda na rasilimali kwa kiasi kikubwa. iliyoathiriwa: BASE HEAD origin/main HEAD Kusimamia Utegemezi wa Mviringo NX pia hutoa ili kutoa grafu ya utegemezi, ambayo inaweza kusaidia katika kugundua mizunguko ya utegemezi. Hati ifuatayo hutumia pato la grafu ya NX kuangalia utegemezi wa duara na itashindwa ikiwa inapatikana. amri iliyojumuishwa Unda faili katika na maudhui yafuatayo: 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(); Hati hii: Hutekeleza amri ya NX ili kutoa grafu ya utegemezi. Husoma grafu kutoka kwa faili ya muda ya JSON. Hukagua mizunguko kwa kujirudia. Huweka hitilafu na kuondoka ikiwa utegemezi wa mviringo umegunduliwa. Kuthibitisha Vitegemezi kwa Vizuizi vya Uzi Miradi inapokua, kudumisha uthabiti katika utegemezi inakuwa changamoto. Utekelezaji wa sheria kali kuhusu utegemezi, matoleo ya Node, na usanidi mwingine ni muhimu ili kuepuka madeni ya kiufundi yasiyo ya lazima. Vizuizi vya Uzi hutoa njia ya kubinafsisha uthibitishaji huu. Kuelewa Vizuizi vya Uzi Vizuizi vya Uzi ni seti ya sheria za vifurushi katika monorepo yako. Faida kubwa ya kuzitumia ni kwamba wewe ndiye msimamizi wa sheria hizi. Kwa mfano, unaweza kuunda sheria ya kulazimisha vifurushi vyote kutumia toleo sawa la React. Mara tu ikiwa imewekwa, hutawahi kukumbana na tatizo wakati programu mwenyeji haiwezi kutumia kipengele/lib na toleo la juu la React. Ingawa kuhamisha monorepo kubwa hadi toleo kuu jipya la utegemezi kunaweza kuwa ngumu, kutumia vizuizi hatimaye huleta uthabiti na uthabiti kwa mradi mzima. Utekelezaji Uthabiti Katika hazina yetu ya mfano, tunatumia faili ya kutekeleza uthabiti kwa: yarn.config.cjs Toleo la Nodi Toleo la Uzi Matoleo ya Dependencies Ili kuruhusu kunyumbulika wakati wa mabadiliko, unaweza kufafanua vizuizi ili kupitisha ukaguzi fulani kwa muda. Kwa mfano: const workspaceCheckExclusions = []; const dependencyCheckExclusions = []; Vidhibiti hivi hukuruhusu kutenga nafasi mahususi za kazi au vitegemezi kutoka kwa mchakato wa uthibitishaji, kuhakikisha uhamiaji laini inapohitajika. Kusimamia Utoaji kwa kutumia Mipangilio ya Mabadiliko Shida nyingine ambayo unaweza kukabiliana nayo na ukuaji wa hazina ni usimamizi wa toleo na kutolewa. Mipangilio ya mabadiliko hutoa suluhisho la kifahari la kugeuza mchakato huu kiotomatiki, kuhakikisha kwamba kila mabadiliko yanafuatiliwa, yanatolewa na kutolewa. Utangulizi wa Mabadiliko ni zana huria iliyoundwa kudhibiti uchapishaji katika hazina za monorepo. Hurahisisha mchakato wa kufuatilia mabadiliko kwa kuyagawa katika hati ndogo zinazoweza kusomeka na binadamu ambazo zinanasa dhamira ya mabadiliko. Hati hizi zinaitwa mabadiliko. Faida kuu ni pamoja na: Changesets Futa Nyaraka Kila kibadilishaji kinaonyesha mabadiliko yaliyofanywa, ambayo husaidia wasanidi programu na watumiaji kuelewa nini cha kutarajia katika toleo jipya. Udhibiti wa Toleo la Punjepunje Kila kifurushi kinatolewa kivyake, na kuhakikisha kuwa vifurushi vilivyoathiriwa pekee ndivyo vinavyosasishwa. Hii inapunguza hatari ya matuta tupu ya toleo na mapumziko ya utegemezi. Ushirikiano-Rafiki Kila mabadiliko yanaporekodiwa kupitia kibadilishaji, timu zinaweza kukagua na kuidhinisha masasisho kabla ya toleo halisi. Matoleo ya Kiotomatiki Moja ya vipengele vya nguvu zaidi vya Changesets ni uwezo wa kufanya mchakato otomatiki. Unaweza kujumuisha Changesets kwenye bomba la CI/CD na usahau kuhusu mabadiliko ya matoleo ya kibinafsi na uchapishaji wa NPM. Angalia mtiririko wa kazi wa katika hazina ya mfano. Ina hatua . Hatua inayoungwa mkono na cha GitHub huunda uchawi wote. Unahitaji tu kusanidi kwa kuchapisha vifurushi vyako. Kisha, kila kushinikiza kwa tawi itakuwa: release.yaml create-release-pull-request-or-publish mabadiliko/kitendo NPM_TOKEN main . Angalia kama kuna hati za Changeset Iwapo hati za kibadilishaji zipo, kitendo hutengeneza ombi la kuvuta kwa kutumia matuta muhimu ya toleo na masasisho ya mabadiliko. Ikiwa hakuna mabadiliko yanayotambuliwa, hakuna kinachotokea. . Angalia kama kuna vifurushi vilivyo tayari kuchapishwa Ikiwa vifurushi viko tayari kutolewa, hatua itachapisha matoleo mapya kwa NPM kwa kutumia iliyotolewa. Ikiwa hakuna vifurushi vilivyo tayari kuchapishwa, kitendo kitaondoka bila kufanya mabadiliko. NPM_TOKEN Kwa kufanyia kazi hizi kiotomatiki, Seti za Mabadiliko huhakikisha kuwa matoleo yako ni thabiti na yanategemewa, hivyo basi kupunguza uwezekano wa makosa ya kibinadamu na kurahisisha utendakazi wako wa ukuzaji. Ujumuishaji wa mtiririko wa kazi na Vitendo vya GitHub Sehemu hii inaangazia jinsi ya kufungua uwezo wa usanifu ambao tumeunda hivi punde. Kwa kutumia Vitendo vya GitHub, tutafanya ukaguzi wa ubora wa PR kiotomatiki, matoleo ya matoleo ya maktaba na vipengele, na utumaji programu. Lengo ni kuongeza uwekaji kiotomatiki huku ukidumisha ubora wa msimbo na uzito wa kazi. Thibitisha Ubora wa PR Ili kuhakikisha kwamba msimbo wa ombi la kuvuta unasalia kuwa thabiti na thabiti, tunaunda mtiririko maalum wa . Mtiririko huu wa kazi hufanya kazi kadhaa, kama vile kuhakikisha kuwa mabadiliko ya toleo la mikono hayatambuliwi (kwa kuwa uchapishaji unadhibitiwa na Changesets): ubora.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 }} Kando ya hundi hii, utegemezi usakinishaji, kuthibitisha vikwazo, hukagua utegemezi wa mduara na kuthibitisha ubora wa jumla wa msimbo kwa kutumia hati tuliyofafanua awali na 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 Ukaguzi wa ubora umeundwa kufanya kazi kwenye vifurushi vilivyoathiriwa na ombi la sasa la kuvuta. Kukamilika kwa kazi hizi kwa mafanikio kunaashiria kwamba ombi la kuvuta liko tayari kuunganishwa (pamoja na kupokea ukaguzi wa misimbo). Ikiwa ukaguzi wa ziada unahitajika kwa mradi wako, unaweza kusasisha hati yako ya na ubora ili kuweka mtiririko wa kazi bila kubadilika. nx.json Chapisha Maktaba na Vipengele Baada ya PR kuunganishwa, mtiririko wa kazi wa kutolewa (kama ilivyofafanuliwa katika sura ya Changesets) huanzishwa. Mtiririko huu wa kazi huunda vifurushi vilivyoathiriwa na kuunda PR na matuta ya toleo. Mara baada ya PR hii kuidhinishwa na kuunganishwa, hutumika tena - wakati huu, badala ya kuunda PR, hutambua mabadiliko ya toleo na kutoa vifurushi vilivyosasishwa kwa 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 }} Kufuatia hili, kazi inayoitwa inatekelezwa, ambayo inawajibika kwa uwekaji wa programu. Inapokea orodha ya vifurushi vilivyochapishwa kutoka kwa hatua ya awali na hutuleta kwenye sura inayofuata. release-apps Chapisha Programu Sehemu ya mwisho ya mchakato wa kutoa inahusisha kupeleka maombi yako (programu hazichapishwi kwa NPM, kwa sababu zimewekwa katika ). Mtiririko wa kazi wa huanzishwa kiotomatiki na , au unaweza kutekelezwa moja kwa moja kutoka kwa kichupo cha Vitendo kwenye 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: "[]" Mtiririko huu wa kazi unakubali uingizaji wa Vifurushi ili kubaini ni vifurushi vipi vimechapishwa. Kwa kutumia mkakati wa matrix, hukagua kila matumizi ya matrix kwa uwepo wa vitegemezi vilivyochapishwa: 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 Ukaguzi huu ni sharti moja la kuanzisha uwekaji wa programu. Masharti mengine yanahakikisha kuwa toleo la programu limebadilishwa (kuashiria kuwa uwekaji upya ni muhimu hata kama hakuna vitegemezi vilivyosasishwa): - 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 Hatimaye, baada ya kuthibitisha kuwa programu ina vitegemezi vilivyosasishwa au toleo lake limebadilika, mtiririko wa kazi hurejesha toleo jipya na kuendelea kuunda na kusambaza programu: - 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 }} Katika mfano huu, tunaunda picha ya Docker bila kuisukuma kwenye Usajili. Katika utendakazi wako wa uzalishaji, badilisha hatua hii na mchakato halisi wa kusambaza. Hitimisho Muhtasari wa Mbinu Bora Katika makala haya yote, tuligundua usanidi wa monorepo thabiti na zana zinazosaidia kuidhibiti kwa ufanisi. Kwa kuweka msingi wako wa msimbo katikati, hutahisisha tu usimamizi wa utegemezi bali pia huboresha ushirikiano kati ya timu zote. Tulionyesha jinsi Uzi unavyoweza kutumiwa ili kushiriki utegemezi, kuharakisha usakinishaji na PnP na kuboresha uthabiti wa jumla wa mradi. Zaidi ya hayo, kuunganisha NX kwa utekelezaji wa hati inayolengwa huhakikisha kuwa CI ni ya haraka na bora. Mipangilio ya mabadiliko ilisaidia kuweka matoleo kiotomatiki, kupunguza hitilafu za mikono na kurahisisha matoleo. Hatimaye, tumetengeneza bomba la CI/CD lililo tayari kwa uzalishaji kwa vitendo vya GitHub ambavyo hufanya kazi zinazohitajika pekee. Hatua Zinazofuata : Anza kwa kusanidi monorepo ya kiwango kidogo ili kujaribu mbinu hizi bora. Jaribu kwa miundo tofauti ya folda, na upanue hatua kwa hatua ili kujumuisha vifurushi zaidi imani yako inapoongezeka. Jaribio na Ubadilishe : Zingatia kujumuisha zana za ziada kama PNPM au Turborepo kulingana na mahitaji ya kipekee ya mradi wako na mapendeleo ya timu. Unganisha Zana za Ziada : Rekebisha utiririshaji kazi wako wa GitHub Actions ili kujumuisha ukaguzi wa ziada wa ubora, ufunikaji wa misimbo, na ukaguzi wa usalama unaolenga mradi wako. Boresha Mabomba ya CI/CD : Endelea kupata taarifa kuhusu matoleo mapya zaidi ya Uzi, NX na Changesets. Shirikiana na jumuiya ili kushiriki maarifa na kujifunza kuhusu mienendo inayoibuka katika usimamizi wa monorepo. Jumuiya na Masasisho Rasilimali : Mfano wa Hifadhi Fikia mfano kamili wa hazina iliyoundwa kwa mwongozo huu. Chunguza muundo wa mradi, sampuli za msimbo, na hati zinazoonyesha usanidi wa monorepo ukifanya kazi. : Vifurushi vya NPM vilivyochapishwa Angalia kifurushi halisi cha NPM kilichochapishwa kama sehemu ya mradi huu. Vifurushi hivi vinaonyesha matumizi ya ulimwengu halisi na utekelezaji wa dhana zilizojadiliwa katika makala.