Hopp til hovedinnhold
Fag i Bekk / Tre verktøy for å unngå ...Tre verktøy for å unngå at prosjektet ...

Tre verktøy for å unngå at prosjektet ditt råtner

Marcus Haaland
23. april

Hver gang vi venter med å oppgradere en pakke, lar vi små, usynlige problemer vokse seg større. Eldre pakker kan skjule sikkerhetshull som en dag gir etter. Andre ganger oppdager vi at vi ikke kan ta i bruk ny og spennende funksjonalitet før vi har ryddet opp i det grunnleggende.

Regelmessige oppdateringer er som vedlikehold av et hus – en spiker her og der er langt bedre enn en full renovering. Enten fikser vi det litt etter litt, eller så våkner vi en dag til fullstendig kollaps. Vi kommer tilbake til hvordan du jevnlig kan spikre, men når du først står i et hav av oppdateringer, hvordan går du frem?

Hvordan oppgradere pakker?

Avhengigheter i en package.json kan se slik ut:

{
  ...
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.14.1",
    "axios": "^1.5.0",
    ...
  },
  "devDependencies": {
    "eslint": "^8.56.0",
    "prettier": "^3.2.5",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-react": "^7.33.2",
    ...
  }
}

Vi har en lang liste avhengigheter, men hvordan vet vi om en pakke er utdatert?

Et nyttig verktøy for å sjekke dette er npm-check-updates, som du kan installere fra npm: https://www.npmjs.com/package/npm-check-updates

Etter installering, kan du med følgende kommando se hva som er nyeste versjon:

ncu -i // -i for interactive

Da får du opp en oversikt over pakkene, og du kan huke av for hvilke pakker du vil oppgradere.

Liste av pakker
"ncu -i" gir deg oversikt over pakkene du har installert.

Du kan selvfølgelig være en råtass og trykke "Enter", og da oppgradere alt på engang, men da er sjansen stor for at noe vil kræsje. For å forstå hva som er en smidigere fremgangsmåte, la oss først ta en tur innom versjonering.

To ord om semver

De fleste pakker følger semantisk versjonering. Det betyr at plassering av tallene i et versjonsnummer har noe å si, henholdsvis major, minor og patch:

  • patch (1.2.3): mindre endring som ikke krever endring fra konsumer av pakken, som en bugfiks eller fiks av sikkerhetshull
  • minor (1.2.3): ny funksjonalitet, som at et bibliotek har lagt til en komponent
  • major (1.2.3): noe som krever at konsumer endrer kode, som endring av en import-sti eller fjerning av en komponent

Siden patch og minor ikke krever endringer fra konsumeren av pakken, skal det i utgangspunktet være trygt å oppgradere patcher og minors. Det er heller når vi oppgraderer breaking changes, majors, at vi må sjekke opp hva som er endret.

Det er også verdt å merke seg at om en pakke fortsatt har 0 i major-versjon (0.2.3), følger ikke pakken nødvendigvis semver. Da kan også patches og minors kreve kodeendringer.

Så gi meg en fremgangsmåte 'a

Når du skal oppgradere pakker, anbefaler jeg deg derfor å starte med patches og minors. For disse pakkene skal du ikke trenge å gjøre kodeendringer.

Da anbefaler jeg deg å gjøre følgende kommando, som gir deg en ganske luksuriøs opplevelse:

ncu -i --format group // Grupperer versjonene 

Da får du denne vakre tabellen, allerede huket av for patches og minors, så du trenger bare å trykke "Enter":

Liste av pakker gruppert etter versjon
ncu har en nyttig kommando som grupperer endringene

Om du så trykker "Enter", oppdaterer den package.json og prompter deg til å kjøre pnpm install, så du får oppdatert lokale filer.

I en perfekt verden du har også tester som du kan kjøre, så du slipper å manuelt sjekke om appen din fortsatt fungerer.

Om alt ser bra ut, commit endringen. Om du oppdager en feil, rull tilbake endringene og bruk interaktiv modus til å oppgradere en og en pakke.

Når alle patches og minors er ferdige, kan vi gå over til major-versjonene, som krever litt mer omtanke.

Hvordan oppgradere major-versjoner?

Major- versjoner består av endringer som kan knekke appen din. Det kan være smått som funksjonalitet som er fjernet, eller en import som er endret, eller større ting, som i React ved at klient-komponenter nå må skrive “use client” i toppen av filene.

Den raskeste veien for å finne endringene, er via et triks jeg lærte nylig. Ved å hovre musepekeren over den relevante pakken i package.json i vscode, får du en lenke til GitHub eller relevant docs:

Musepeker over pakken gir versjonsnummer og dokumentasjons-lenke
Musepeker over pakken gir versjonsnummer og dokumentasjons-lenke

Innpå GitHub kan du ofte lese deg opp på endringer, enten i changelog:

Skjermbilde av CHANGELOG.md på GitHub
På pakkens GitHub-prosjekt kan du lese endringer i changelog.md

eller releases:

Skjermbilde av releases på GitHub
... eller lese endringer i releases

Så kan du bla deg ned til notatet om den relevante major-versjonen:

Skjermbilde av endringer fra en versjon
Release inkluderer ofte en kort setning om hva som er endret

Noen ganger er denne teksten nok til å oppgradere. Om du er heldig, bruker du ikke det som er endret, så du slipper unna endringer.

For større endringer, følger det ofte en bloggpost. For eksempel innebar eslint fra versjon 8 til 9 en endring i navn på filer og hvordan koden skulle struktureres. Da fulgte det en lengre bloggpost for å hjelpe utvikleren å migrere: https://eslint.org/docs/latest/use/migrate-to-9.0.0

Unngå skippertak med dependabot

Du har sikkert dependabot i kodeprosjektet ditt allerede, men jeg vil minne deg om å også bruke det – for å unngå slike store oppgraderings-skippertak.

Når du først legger til dependabot i prosjektet, som du enkelt kan gjøre via GitHub-innstillinger, får du jevnlig opp oppgraderinger av pakker:

Dependabot åpner PR-er for oppgradering av pakker
Dependabot åpner PR-er for oppgradering av pakker

Når du trykker inn på dependabot-PR-en, får du opp release-notes, så du kan sjekke for hva som er endret. Ganske praktisk, får du også opp sjansen for at den nye oppgraderingen feiler bygget. Om den er nærmere 100%, kan du ganske trygt merge den.

Men aller helst bør du ha egen CI hvor du bygger og tester prosjektet. Om du ikke har det, bør du sjekke inn i branchen, og sjekke om oppgraderingen gikk bra, som nevnt i første punkt lenger oppe.

Dependabot lager en PR, med release-notes og kompatibilitets-sjekk
Dependabot lager en PR, med release-notes og kompatibilitets-sjekk

Om alt ser bra ut, kan du merge denne oppgraderingen. Dependabot er dermed en fin måte å holde kodeprosjektet oppdatert og sikkert.

Den beste oppgraderingen er den du slipper

Tittet du på bloggposten for oppgradering av eslint? Da fikk du kanskje samme tanke som meg: den er veldig lang!

Tidligere i år satt jeg og to andre utviklere og mob-programmerte for å oppgradere en rekke major-versjoner. Selv med en bloggpost og god rubberducking, kan det fortsatt være en god dose spaghetti-avhengigheter du må navigere i, før prosjektet bygger uten noen feil.

Det fikk meg til å tenke på visdomsord jeg fikk fra mine seniorkollegaer da jeg først startet: "Trenger du den pakken?". Jeg, som fersk, stolte nå mer på pakker brukt av tusenvis, enn min vesle kode.

Når du legger til en pakke, sparer du tid der og da. Men du kjøper også gjeld, når du senere må sørge for at pakken er oppgradert. Så vil du spare tid nå eller senere? Og har du rutinene for å holde prosjektet vedlike?

Det er greit å ta i bruk pakker, men et triks er også å fjerne dem når du ikke lenger trenger dem. Som det fins verktøy for å sjekke hvilke av pakker du har som trenger kjærlighet, så fins det også verktøy for å sjekke hvilke pakker du kan drepe.

depcheck gjør nettopp det. Med følgende kommando:

npx depcheck

Får du output om hvilke pakker den tror du ikke bruker:

Liste av ubrukte avhengigheter
Liste av ubrukte avhengigheter

Jeg sier tror, for jeg er ganske sikker på at hvert fall to av disse pakkene er i bruk. Men da er det igjen to andre pakker jeg er enig at ikke brukes. Ved å fjerne disse, har du mindre støy fra dependabots og kanskje to pakker du slipper å utøve ninjamanøvere for å kunne oppgradere.

Avsluttende ord

Å holde avhengighetene oppdatert trenger ikke å føre til total kollaps – verken for prosjektet ditt eller energinivået ditt. Med disse tre verktøyene kommer du langt, både for å unngå skippertak og for å møte oppgraderingskaoset med litt mer selvtillit.