Utforsk kraften i frontend-monorepos med Lerna og Nx. Lær om arbeidsområdebehandling, kodedeling og effektive bygg for storskala-prosjekter.
Frontend Monorepo: Arbeidsområdebehandling med Lerna og Nx
I det stadig utviklende landskapet for frontend-utvikling, kan det være en betydelig utfordring å håndtere store og komplekse prosjekter. Tradisjonelle oppsett med flere repositorier, selv om de tilbyr isolasjon, kan føre til duplisering av kode, hodebry med avhengighetsstyring og inkonsistent verktøybruk. Det er her monorepo-arkitekturen kommer til sin rett. Et monorepo er ett enkelt repositorium som inneholder flere, ofte relaterte, prosjekter som bygges og versjoneres sammen. Denne tilnærmingen gir mange fordeler, men for å håndtere et monorepo effektivt kreves spesialiserte verktøy. Denne artikkelen utforsker to populære løsninger: Lerna og Nx.
Hva er et monorepo?
Et monorepo er et versjonskontrollsystem-repositorium som inneholder koden for mange prosjekter. Disse prosjektene kan være relaterte eller helt uavhengige. Nøkkelen er at de deler det samme repositoriet. Selskaper som Google, Facebook, Microsoft og Uber har med suksess tatt i bruk monorepos for å håndtere sine massive kodebaser. Tenk deg at Google lagrer nesten all sin kode, inkludert Android, Chrome og Gmail, i ett enkelt repositorium.
Fordeler med et monorepo
- Kodedeling og gjenbruk: Del enkelt kode mellom prosjekter uten komplekse pakke- og publiseringsprosesser. Forestill deg et designsystembibliotek som sømløst kan integreres i flere applikasjoner innenfor samme repositorium.
- Forenklet avhengighetsstyring: Håndter avhengigheter på ett sted, noe som sikrer konsistens på tvers av alle prosjekter. En oppdatering av en avhengighet i et delt bibliotek oppdaterer automatisk alle prosjekter som er avhengige av det.
- Atomiske endringer: Gjør endringer som spenner over flere prosjekter i én enkelt commit, noe som sikrer konsistens og forenkler testing. For eksempel kan en refaktorering som påvirker både frontend og backend gjøres atomisk.
- Forbedret samarbeid: Team kan enkelt samarbeide om forskjellige prosjekter i samme repositorium, noe som fremmer kunnskapsdeling og tverrfaglig utvikling. Utviklere kan enkelt bla gjennom og forstå kode på tvers av forskjellige team.
- Konsistente verktøy og praksiser: Håndhev konsistente kodestandarder, linting-regler og byggeprosesser på tvers av alle prosjekter. Dette forbedrer kodekvaliteten og vedlikeholdbarheten.
- Forenklet refaktorering: Storskala refaktoreringprosjekter blir enklere siden all relatert kode er innenfor samme repositorium. Automatiserte refaktoreringverktøy kan brukes på hele kodebasen.
Utfordringer med et monorepo
- Repositoriumstørrelse: Monorepos kan bli veldig store, noe som potensielt kan senke kloning- og indekseringsoperasjoner. Verktøy som `git sparse-checkout` og `partial clone` kan bidra til å redusere dette problemet.
- Byggetider: Å bygge hele monorepoet kan være tidkrevende, spesielt for store prosjekter. Verktøy som Lerna og Nx tilbyr optimaliserte byggeprosesser for å løse dette.
- Tilgangskontroll: Å begrense tilgangen til spesifikke deler av monorepoet kan være komplisert. Nøye planlegging og implementering av tilgangskontrollmekanismer er nødvendig.
- Verktøykompleksitet: Oppsett og administrasjon av et monorepo krever spesialiserte verktøy og kunnskap. Læringskurven kan være bratt i begynnelsen.
Lerna: Håndtering av JavaScript-prosjekter i et monorepo
Lerna er et populært verktøy for å håndtere JavaScript-prosjekter i et monorepo. Det optimaliserer arbeidsflyten rundt håndtering av repositorier med flere pakker med Git og npm. Det er spesielt godt egnet for prosjekter som bruker npm eller Yarn for avhengighetsstyring.
Nøkkelfunksjoner i Lerna
- Versjonskontroll: Lerna kan automatisk versjonere og publisere pakker basert på endringer gjort siden siste utgivelse. Den bruker 'conventional commits' for å bestemme neste versjonsnummer.
- Avhengighetsstyring: Lerna håndterer avhengigheter mellom pakker, og sikrer at pakker innenfor monorepoet kan være avhengige av hverandre. Den bruker symlinking for å opprette lokale avhengigheter.
- Oppgavekjøring: Lerna kan kjøre kommandoer på tvers av flere pakker parallelt, noe som fremskynder bygge- og testprosesser. Den støtter kjøring av skript definert i `package.json`.
- Endringsdeteksjon: Lerna kan oppdage hvilke pakker som har endret seg siden siste utgivelse, noe som muliggjør målrettede bygg og distribusjoner.
Eksempel på bruk av Lerna
La oss illustrere Lernas bruk med et forenklet eksempel. Anta at vi har et monorepo med to pakker: `package-a` og `package-b`. `package-b` er avhengig av `package-a`.
monorepo/
├── lerna.json
├── package.json
├── packages/
│ ├── package-a/
│ │ ├── package.json
│ │ └── index.js
│ └── package-b/
│ ├── package.json
│ └── index.js
1. Initialiser Lerna:
lerna init
Dette oppretter `lerna.json` og oppdaterer rot-`package.json`. Filen `lerna.json` konfigurerer Lernas oppførsel.
2. Installer avhengigheter:
npm install
# eller
yarn install
Dette installerer avhengigheter for alle pakker i monorepoet, basert på `package.json`-filene i hver pakke.
3. Kjør en kommando på tvers av pakker:
lerna run test
Dette kjører `test`-skriptet som er definert i `package.json`-filene til alle pakker som har det definert.
4. Publiser pakker:
lerna publish
Denne kommandoen analyserer commit-historikken, bestemmer hvilke pakker som har endret seg, øker versjonene deres basert på 'conventional commits', og publiserer dem til npm (eller ditt valgte register).
Lerna-konfigurasjon
Filen `lerna.json` er hjertet i Lernas konfigurasjon. Den lar deg tilpasse Lernas oppførsel, slik som:
- `packages`: Spesifiserer plasseringen av pakkene i monorepoet. Ofte satt til `["packages/*"]`.
- `version`: Spesifiserer versjoneringsstrategien. Kan være `independent` (hver pakke har sin egen versjon) eller en fast versjon.
- `command`: Lar deg konfigurere alternativer for spesifikke Lerna-kommandoer, som `publish` og `run`.
Eksempel på `lerna.json`:
{
"packages": [
"packages/*"
],
"version": "independent",
"npmClient": "npm",
"useWorkspaces": true,
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore(release): publish"
}
}
}
Nx: Smart, raskt og utvidbart byggesystem
Nx er et kraftig byggesystem som gir avanserte funksjoner for monorepo-behandling. Det fokuserer på inkrementelle bygg, resultat-caching og oppgaveorkestrering for å betydelig forbedre byggetider og utviklerproduktivitet. Mens Lerna primært fokuserer på å håndtere pakker, gir Nx en mer helhetlig tilnærming til å håndtere hele monorepo-arbeidsflyten, inkludert kodegenerering, linting, testing og distribusjon.
Nøkkelfunksjoner i Nx
- Inkrementelle bygg: Nx analyserer avhengighetsgrafen til prosjektene dine og bygger bare de prosjektene som har endret seg siden siste bygg. Dette reduserer byggetidene dramatisk.
- Resultat-caching: Nx cacher resultatene av oppgaver, som bygg og tester, slik at de kan gjenbrukes hvis input ikke har endret seg. Dette fremskynder utviklingssyklusene ytterligere.
- Oppgaveorkestrering: Nx tilbyr et kraftig system for oppgaveorkestrering som lar deg definere komplekse byggepipelines og utføre dem effektivt.
- Kodegenerering: Nx tilbyr kodegenereringsverktøy som kan hjelpe deg med å raskt opprette nye prosjekter, komponenter og moduler, i tråd med beste praksis og konsistente standarder.
- Plugin-økosystem: Nx har et rikt plugin-økosystem som støtter ulike teknologier og rammeverk, som React, Angular, Node.js, NestJS og mer.
- Visualisering av avhengighetsgraf: Nx kan visualisere avhengighetsgrafen til monorepoet ditt, og hjelpe deg med å forstå forholdet mellom prosjekter og identifisere potensielle problemer.
- Påvirkede kommandoer: Nx tilbyr kommandoer for å kjøre oppgaver kun på de prosjektene som er påvirket av en spesifikk endring. Dette lar deg fokusere innsatsen på de områdene som trenger oppmerksomhet.
Eksempel på bruk av Nx
La oss illustrere Nxs bruk med et forenklet eksempel. Vi vil opprette et monorepo med en React-applikasjon og et Node.js-bibliotek.
1. Installer Nx CLI globalt:
npm install -g create-nx-workspace
2. Opprett et nytt Nx-arbeidsområde:
create-nx-workspace my-monorepo --preset=react
cd my-monorepo
Dette oppretter et nytt Nx-arbeidsområde med en React-applikasjon. `--preset=react`-alternativet forteller Nx at arbeidsområdet skal initialiseres med React-spesifikke konfigurasjoner.
3. Generer et bibliotek:
nx generate @nrwl/node:library my-library
Dette genererer et nytt Node.js-bibliotek kalt `my-library`. Nx konfigurerer automatisk biblioteket og dets avhengigheter.
4. Bygg applikasjonen:
nx build my-app
Dette bygger React-applikasjonen. Nx analyserer avhengighetsgrafen og bygger bare de nødvendige filene på nytt.
5. Kjør tester:
nx test my-app
Dette kjører enhetstestene for React-applikasjonen. Nx cacher testresultatene for å fremskynde påfølgende testkjøringer.
6. Se avhengighetsgrafen:
nx graph
Dette åpner et webgrensesnitt som visualiserer avhengighetsgrafen til monorepoet.
Nx-konfigurasjon
Nx konfigureres gjennom filen `nx.json`, som ligger i roten av arbeidsområdet. Denne filen definerer prosjektene i arbeidsområdet, deres avhengigheter og oppgavene som kan kjøres på dem.
Viktige konfigurasjonsalternativer i `nx.json` inkluderer:
- `projects`: Definerer prosjektene i arbeidsområdet og deres konfigurasjon, som rotkatalogen og byggemål.
- `tasksRunnerOptions`: Konfigurerer oppgavekjører, som er ansvarlig for å utføre oppgaver og cache resultatene.
- `affected`: Konfigurerer hvordan Nx bestemmer hvilke prosjekter som er påvirket av en endring.
Eksempel på `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: Hvilken skal man velge?
Både Lerna og Nx er utmerkede verktøy for å håndtere frontend-monorepos, men de dekker litt forskjellige behov. Her er en sammenligning for å hjelpe deg med å velge den rette for ditt prosjekt:
| Funksjon | Lerna | Nx |
|---|---|---|
| Fokus | Pakkehåndtering | Byggesystem og oppgaveorkestrering |
| Inkrementelle bygg | Begrenset (krever eksterne verktøy) | Innebygd og høyt optimalisert |
| Resultat-caching | Nei | Ja |
| Kodegenerering | Nei | Ja |
| Plugin-økosystem | Begrenset | Omfattende |
| Læringskurve | Lavere | Høyere |
| Kompleksitet | Enklere | Mer komplekst |
| Bruksområder | Prosjekter som primært fokuserer på å håndtere og publisere npm-pakker. | Store og komplekse prosjekter som krever optimaliserte byggetider, kodegenerering og et omfattende byggesystem. |
Velg Lerna hvis:
- Du primært trenger å håndtere og publisere npm-pakker.
- Prosjektet ditt er relativt lite til middels stort.
- Du foretrekker et enklere verktøy med en lavere læringskurve.
- Du allerede er kjent med npm og Yarn.
Velg Nx hvis:
- Du trenger optimaliserte byggetider og inkrementelle bygg.
- Du ønsker kodegenereringsfunksjonalitet.
- Du krever et omfattende byggesystem med oppgaveorkestrering.
- Prosjektet ditt er stort og komplekst.
- Du er villig til å investere tid i å lære et kraftigere verktøy.
Kan man bruke Lerna med Nx?
Ja, Lerna og Nx kan brukes sammen. Denne kombinasjonen lar deg utnytte Lernas pakkehåndteringsfunksjoner samtidig som du drar nytte av Nxs optimaliserte byggesystem og oppgaveorkestrering. Nx kan konfigureres som en oppgavekjører for Lerna, og gir inkrementelle bygg og resultat-caching for Lerna-administrerte pakker.
Beste praksis for frontend monorepo-behandling
Uavhengig av om du velger Lerna eller Nx, er det avgjørende å følge beste praksis for å lykkes med å håndtere et frontend-monorepo:
- Etabler en klar prosjektstruktur: Organiser prosjektene dine logisk og konsistent. Bruk en tydelig navnekonvensjon for pakker og biblioteker.
- Håndhev konsistente kodestandarder: Bruk lintere og formaterere for å sikre en konsistent kodestil på tvers av alle prosjekter. Verktøy som ESLint og Prettier kan integreres i arbeidsflyten din.
- Automatiser bygge- og testprosesser: Bruk CI/CD-pipelines for å automatisere bygge-, test- og distribusjonsprosesser. Verktøy som Jenkins, CircleCI og GitHub Actions kan brukes.
- Implementer kodegjennomganger: Utfør grundige kodegjennomganger for å sikre kodekvalitet og vedlikeholdbarhet. Bruk pull requests og verktøy for kodegjennomgang.
- Overvåk byggetider og ytelse: Spor byggetider og ytelsesmetrikker for å identifisere flaskehalser og områder for forbedring. Nx tilbyr verktøy for å analysere byggeytelse.
- Dokumenter monorepo-strukturen og prosessene: Lag tydelig dokumentasjon som forklarer strukturen til monorepoet ditt, verktøyene og teknologiene som brukes, og utviklingsarbeidsflytene.
- Ta i bruk 'conventional commits': Bruk 'conventional commits' for å automatisere versjonerings- og utgivelsesprosesser. Lerna støtter 'conventional commits' ut av boksen.
Konklusjon
Frontend-monorepos gir betydelige fordeler for håndtering av store og komplekse prosjekter, inkludert kodedeling, forenklet avhengighetsstyring og forbedret samarbeid. Lerna og Nx er kraftige verktøy som kan hjelpe deg med å effektivt håndtere et frontend-monorepo. Lerna er et godt valg for å håndtere npm-pakker, mens Nx tilbyr et mer omfattende byggesystem med avanserte funksjoner som inkrementelle bygg og kodegenerering. Ved å nøye vurdere prosjektets behov og følge beste praksis, kan du lykkes med å ta i bruk et frontend-monorepo og høste fordelene.
Husk å vurdere faktorer som teamets erfaring, prosjektets kompleksitet og ytelseskrav når du velger mellom Lerna og Nx. Eksperimenter med begge verktøyene og finn det som passer best for dine spesifikke behov.
Lykke til på din monorepo-reise!