Slik skriver du kode i Jøkul
Jøkul er et fellesprosjekt for alle i Fremtind. Det vil si at det også er ditt.
Utviklingsmiljø
Jøkul er et fellesprosjekt for alle i Fremtind. Det vil si at det også er ditt.
Å programmere i Jøkul er ganske likt annen frontendprogrammering. Forskjellen fra når du lager en app er at vi lager bibliotek som brukes i apper. I praksis vil du sjeldent merke noen stor forskjell, med mindre du skal lage helt nye pakker eller jobbe med infrastrukturen i Jøkul.
Før du setter i gang er det lurt å ha sett på Bidra til designsystemet.
Vi har også egne stilguider for Sass og React.
Om du er usikker på noe eller står fast er det kort vei til å få hjelp på Discussions, Support Designsystem på Teams, eller ved å spørre noen på designsystemforum. Dette må være installert på maskinen for å jobbe i Jøkul:
Når maskinen er klar er det tre steg for å komme i gang:
- Klon Jøkul-biblioteket fra GitHub (du kan lage deg en fork om du ikke har tilgang, eller høre med nærmeste leder om å bli lagt til i GitHub-organisasjonen)
- Lag en ny branch basert på
main
-branchen - Bygg prosjektet med kommandoen
pnpm boot
Her finner du pakkene
Alle komponentene er organisert under mappen packages. De som slutter på -react
er React-pakker. De som ikke har enendelse, er stilpakker.
Grunnen til at vi deler opp i React- og stilpakker er for å kunne la for eksempel et CMS som ikke er laget med React fremdeles bruke Jøkul-stiler.
Eksempel på en endring
La oss si at vi savner en prop fra en av typedefinisjonene i Jøkul. LoaderProps
mangler muligheten for å gi den en id
. Hvordan legger vi den til?
export interface LoaderProps {// TODO: legg til ID-propclassName?: string;}
Før vi gjør en endring er det greit å sjekke at vi har en oppdatert main
-branch. Om det er første gang vi gjør en endring i Jøkul må vi ha kjørt pnpm boot
.
Gjør endringen på en ny branch
Med oppdatert main
er det klart for å lage en branch:
Her har vi valgt å se på dette som en ny feature. Om dette hadde vært en bugfix ville det vært naturlig å starte branchnavnet med fix/
.
Med branchen vår klar er det på tide å gjøre endringen:
export interface LoaderProps {id?: string;className?: string;}
Før vi lager en commit er det lurt å sjekke at endringen vår ikke har ødelagt noe. For å være helt sikker kan du kjøre kommandoene pnpm build
og pnpm ci:test
på toppnivå i Jøkul (altså ./
, ikke i mappen ./packages/loader-react
). Det kan ta litt tid.
I akkurat dette tilfellet har vi bare endret en typedefinisjon, så det holder å kjøre pnpm typecheck
. Hvis det ikke kommer noen feilmeldinger er alt klart for å lage en commit.
Visuelle regresjonstester
De aller fleste komponentene i Jøkul har visuelle regresjonstester, for å ha en måte å fange opp uventede visuelle endringer. Disse testene baserer seg på snapshots. Snapshots er skjermbilder av komponentens eksempler, tatt av Cypress. Cypress sammenligner utseendet på branchen din med disse skjermbildene.
Hvis du gjør en villet endring i utseendet til en komponent må mappen <pakkenavn>-react/integration/__image_snapshots__
slettes. GitHub Actions vil generere nye snapshots for deg.
I vårt tilfelle er det ingen visuell endring, så vi hopper over dette steget.
Kort om enhetstester
I dette eksempelet hopper vi over enhetstester, men for en endring som fikser en bug eller legger til funksjonalitet ville vi ha skrevet noen. Enhetstester skal ligge sammen med komponenten, med filnavn på formen <MinKomponent>.test.tsx
eller <minFunksjon>.test.ts
.
Enhetstestene skal sikre at nøkkelfunksjonaliteten til komponenten virker. For eksempel kan testene for en knapp sjekke at den blir rendret til DOM, og at den kaller riktig funksjon når man klikker på den.
Vi bruker Jest som test runner og React testing library for å håndtere React-komponenter.
Lag en commit
Til å lage commits bruker vi kommandoen pnpm commit
. Grunnen til det er at commitmeldingene brukes for å generere changelogs og versjonsnummer basert på Semantic Versioning. Det kan vi gjøre fordi pnpm commit
formaterer commitmeldinger på en spesiell måte kalt Conventional Commits. Hvis en commitmelding starter med feat:
vil det automatisk lages en minor-release av pakken som ble endret.
Når vi kjører pnpm commit
startes det en veiviser. Her blir du bedt om å velge hvilken type endring vi har gjort. I vårt tilfelle velger vi feat:
. Du kan skrive typen, eller velge med piltastene. Trykk Enter.
Neste trinn i veiviseren er commit-tittelen. Her skriver du kort hva som er gjort, for eksempel la til id i LoaderProps
. Trykk Enter.
Neste trinn er en valgfri commit body. Her vil mange kanskje foretrekke å bare trykke Enter og heller gjøre en git commit --amend
senere for å bruke en annen editor for å skrive. Vi trykker bare Enter og går videre.
Vi blir spurt om vi har noen BREAKING CHANGES. Vi har ikke det denne gangen. Hvis du har det, beskriv dem her. Hvis en commitmelding har BREAKING CHANGE:
i footeren vil det automatisk lages en major-release av pakken som ble endret.
Til slutt blir vi spurt om å liste ISSUES CLOSED. Her kan du skrive issue-nummeret fra GitHub (inkludert #
, f. eks. #1234
) dersom endringen din vil gjøre at et issue kan lukkes.
Del branchen din
Puh! Det var en del steg. Alt dette er for at automatikken ved publisering skal fungere riktig.
Nå kan du pushe endringen din og åpne en pull request.
Pull requests
Pull requests (PR) lager du på GitHub. Vanligvis er det main
-branchen du setter som base, og branchen med endringene dine du setter som compare.
Når du lager en PR blir du vist et skjema med en mal som kan fylles ut. Det er supert om du gir en kort beskrivelse av innholdet i pull requesten, og lenker til relevante issues og discussions. Sjekk gjerne også av punktene i sjekklisten ved å endre [ ]
til [x]
.
Ta gjerne en titt på Labels og se om noen av dem er relevante for pull requesten din. Som Reviewers kan du bruke forslagene fra GitHub om du vil, eller velge en kollega fra teamet ditt.
Automatiske sjekker
GitHub fanger opp når det lages en pull request, eller det pushes endringer til en branch som har en åpen PR. Når dette skjer kjøres det en workflow på GitHub Actions. Workflowen sørger for å bygge prosjektet, kjøre enhetstester, visuelle regresjonstester, og publisere en forhåndsvisning av jokul.fremtind.no med endringene dine.
Du kan følge med på workflowen i Actions-fanen på GitHub. Der kan du også se at kjøretiden for hele workflowen vanligvis ligger på mellom 15-20 minutter. Hvem skal godkjenne pull requesten?
Vi har ikke noen regler for hvem som skal godkjenne en endring, annet enn at minst én kollega må gi en Approve og at de automatiske sjekkene må kjøre uten feil. Hvis du gjør en stor endring eller introduserer en ny komponent er det fint om du venter litt så flere får muligheten til å gjøre en review. Bruk magefølelsen!
Jøkul-teamet får varsler i GitHub når det kommer nye pull requests og kommer kanskje med en review uoppfordret, men sett gjerne fremtindelise
og piofinn
eksplisitt som reviewers. Du trenger ikke vente på at alle reviewers gir svar.
Hvor lenge må du vente?
Hvor lang tid det tar fra en pull request blir laget til den er reviewet og merget varierer, men de fleste vil bli reviewet og merget innen en arbeidsdag. Hvis en pull request introduserer en ny komponent eller større endringer kan det ta noen dager med iterasjoner før en pull request blir godkjent og merget
Publisering av endringer
Når en pull request merges til main
skjer det en automatisk publisering. Her får vi endelig uttelling for jobben som blir gjort med å skrive commit-meldinger på måten vi gjør i Lag en commit.
Vi bruker GitHub Actions på en liknende måte som ved pull requests. Når workflowen er ferdig finner du oppdaterte pakker på npmjs.com og GitHub Packages. Versjonsnummeret blir bestemt av Lerna, som bruker commitmeldingene for å bestemme om det skal lages en ny major, minor, eller patch-versjon. Pakkenes CHANGELOG.md
blir oppdatert med innholdet fra commitmeldinger. I tillegg har det blitt publisert en oppdatert versjon av jokul.fremtind.no.
Kort om infrastrukturen til Jøkul
Vi organiserer koden i et monorepo og bruker Lerna for å holde kontroll på de individuelle pakkene i repositoriet. Hver enkelt pakke følger semantisk versjonering. Nye versjoner og Changelog blir automatisk generert fra commit-loggen basert på Conventional commits.
Dokumentasjonen vedlikeholdes i CMSet Payload og selve portalen er en Remix app som kjører på AWS.
Slik lager du en ny pakke
- Gå til rot, kjør kommandoen
pnpm scaffold
, og følg instruksene i terminalen. - Etter kommandoen har kjørt vil det være opprettet to mapper i packages mappen (komponent-navn og komponent-navn-react).
Vi har noen minstekrav til dokumentasjon som den nye komponenten din må følge. Disse kravene gjelder dokumentasjonen som vises under Komponenter. I tillegg må det ligge en Figma-branch klar til å merges inn i Jøkul-biblioteket som dokumenterer komponenten og alle varianter. Tiden mellom merging av kode og merging av design må være så kort som mulig.
Må-krav:
- Ingress med kort beskrivelse av komponenten
- Første eksempel synlig uten å scrolle
- Relevante eksempler på riktig og feil bruk
- Live kodeeksempel (oppdateres med valgte egenskaper)
- React-props for komponentene i bunnen
I tillegg har vi noen vil-ønsker. Disse er det fint om du har med fordi de gjør det lettere for andre å bruke komponenten, men de er ikke et krav.
- Kontrollspørsmål for bruk
- Lenker til relevante eller alternative komponenter der det er naturlig
- Eksempler på bruk ute i teamene
Du kan se på dokumentasjonen for Tag og Alert message for inspirasjon.
Slik legger du til en avhengighet
Det finnes avhengigheter på ulike nivåer i Jøkul. Globale avhengigheter, for eksempel de som trengs til å kjøre en byggejobb, ligger på rotnivå. Du kan legge til en ny pakke på rotnivå, med kommandoen pnpm add pakke -w
. For å legge til som en utviklingsavhengighet bruker du -w -D
.
Lokale avhengigheter, som trengs for at en pakke skal fungere i bruk, legger vi vanligvis på pakkenivå. Se "Slik lenker du pakker sammen". Bruk kommandoen pnpm add
for å legge til pakker som ikke er en del av Jøkul. Alternativt kan du bruke lerna add. Før du gjør det, er det lurt å tenke på om de skal sendes med komponenten eller om brukeren av komponenten har ansvaret for å ha avhengigheten i sitt prosjekt. React bør for eksempel være en peerDependency
, slik at brukeren ikke ender opp med flere utgaver av React i sin pakke.