En arkitektur for innovasjon med React-Native (del 2): Kryssplattform byggeklosser med styled-components
I denne posten får du lese litt om hvordan et lite tverrfaglig team i Fremtind arbeider med konsept- og produktutvikling. Vi benytter rammeverk som React-Native, Expo, styled-components og Storybook til å gjenbruke kode og komponenter på kryss av web- og mobilplattformene og tester ut konsepter i et høyt tempo.
Dette er del 2 av en serie på 5 bloggposter hvor vi ser nærmere på hvordan vi benytter React-Native for å gjøre et lite team på to i stand til å teste og utvikle konsepter for alle plattformer.
I forrige post delte vi litt om hvordan React-Native og Expo strømlinjeformer hele prosessen fra prototype til produksjon. I denne posten skal vi se litt nærmere på hvordan du kan lage et komponentbibliotek for alle plattformene ved hjelp av react-native og styled-components.
- En arkitektur for innovasjon med React-Native (del 1): Expo
- → En arkitektur for innovasjon med React-Native (del 2): Kryssplattform byggeklosser med styled-components
- En arkitektur for innovasjon med React-Native (del 3): Storybook️
- En arkitektur for innovasjon med React-Native (del 4): Supernova Studio / FramerX / BuilderX
- En arkitektur for innovasjon med React-Native (del 5): Når er React-Native det riktige valget?
I ukene fremover vil vi også open-source vårt seedprosjekt for å enkelt komme i gang med tech-stacken vår slik at lesere kan gjøre seg sine egne erfaringer med teknologiene.
Silver bullets
Å kunne tilby et enhetlig, brukervennlig og tilgjengelig grensesnitt på samtlige plattformer og minimere duplisering av kode byr på både fordeler og utfordringer. Man kan spare store ressurser på lang sikt ved å kunne teste, utvikle og drifte én felles pakke med byggeklosser og redusere overflaten for feil. Det blir også enklere å parallellisere arbeid og dokumentere og kommunisere på tvers av vertikaler, men et felles komponentbibliotek fører også med seg utfordringer som er viktig at man håndterer godt for at det skal gi verdi.
Noen krav vi stiller til et slik komponentbibliotek:
- et intuitivt og lite rigid API slik at konsumentene lett kan få til det de ønsker og ha muligheten til å overstyre når det trengs
- tilrettelagt for tilgjengelighet (korrekt bruk av ARIA/accessibility attributter)
- tilrettelagt for ytelse (code-splitting, critical CSS extraction)
- lett å vedlikeholde (oversiktlig, lett å utvide og endre, og enkelt å teste)
Med dette som målsetting skal vi se nærmere på hvordan vi kan få til dette i praksis.
CSS — C(ancer/ascading) Style Sheets
Stilark definerer utseende og presentasjon av elementene spesifisert i HTML, være seg farger, hvordan innholdet skal flyte på ulike skjermstørrelser eller animasjoner.
En (av mange) utfordringer på større utviklingsprosjekter er at stilark kan bli komplekse og uryddige. Små endringer kan få store konsekvenser og en liten fiks på profilsiden kan fort ødelegge alt på hovedsiden. Det blir vanskelig å holde styr på hvilken styling som faktisk er i bruk og hvilken innvirkning en endring ett sted kan ha på resten av systemet.
Noen av grunnen til at CSS er så vanskelig å vedlikeholde er hvordan det er knyttet til markupen, hvordan cascading lager hodebry, og hvordan de ulike nettlesermotorene velger å tolke det (les mer). Dette har sine fordeler og ulemper, men kompliserer bruken i et designsystem til apputvikling betraktelig.
Etterhvert har ulike løsninger dukket opp som har forsøkt å enten flytte kompleksiteten over i byggsteg eller redusere den ved hjelp av ulike regelsett som utviklerne må følge: BEM (Block Element Modifier), OOCSS (Object-oriented CSS), Atomic CSS, autoprefixing, CSS modules m.fl.
Noen av utfordringene:
- Det er komplekst å sette opp byggsteg for å bearbeide stilarkene med autoprefixing, minifying, CSS-modules og lignende
- Å benytte regelsett som BEM, Atomic CSS o.l. gir mer rom for menneskelige feil
- Det skaper mere kompleksitet og overhead å gjenbruke. Man må forstå hvordan komponentenes HTML og CSS henger sammen, og det krever mere dokumentasjon for å kunne benytte biblioteket effektivt
- Det er vanskelig å oppdage hvilke klasser og selectorer som ikke lenger har noen effekt og kan/burde fjernes
- Det er vanskelig for en designer selv med HTML og CSS erfaring å endre styling
For å unngå disse problemene og gjøre det enkelt for konsument av komponentbiblioteket å gjøre de riktige tingene har jeg noen ønsker:
- Konsument skal kun trenge å forholde seg til et dokumentert og enkelt API. Underliggende semantikk blir abstrahert bort (importer ferdige byggeklosser heller enn ingredienser til å bygge komponenten selv på nytt)
- Komponenten skal fungere på alle plattformer
- Fjerner man en komponent får man hjelp til å rydde opp i ubrukt styling av IDE
- Liten til ingen kompleksitet i byggsteg
- Lett å lese og arbeide med for noen som kjenner til CSS
- Unngå global styling og konflikter
Du kan lese mer om fordeler og ulemper med CSS-in-JS her
Et alternativ som oppfylte alle disse ønskene i høy grad er en CSS-in-JS variant kalt styled-components.
Ready, set, code 🚀
Ved hjelp av rammeverk som styled-components, react-native-reanimated, react-native-gesture-handler og hooks er man fri til å lage dynamiske, interaktive, komplekse og brukervennlige byggeklosser som fungerer på alle plattformene. Ved å åpne opp for at konsumenten kan sende inn ulike parametere, overrides og callbacks kan man tilrettelegge for at byggeklossene forenkler og effektiviserer arbeidsflyten og gjør hverdagen enklere for utviklerne som benytter de.
Byggeklossene kan importeres og gjenbrukes 100% uten at forbruker trenger å forholde seg til stilarkene. Stilen blir knyttet og scopet til komponenten og tilpasset til nettleseren run-time (løser problemene som bl.a. autoprefixing og CSS-modules løser). Man slipper altså unna global styling og komplekse byggsteg.
Slik ser implementasjonen av en typisk styled-component basert komponent ut:
Man kan også gjøre mere avanserte ting som arv, stiler som endrer seg basert på komponentens parametere eller state:
~styles:
Man har altså muligheten til å ta i bruk alle verktøyene man har til utvikling av javascript, som tree-shaking, code-splitting, minifying, sterke typer (typescript) og annet som gjør det lettere for utvikleren å utvikle løsninger som er av høy kvalitet og ytelse.
Fungerende eksempel du kan leke deg med, åpne i ekstern editor for å se full visning og editor og forhåndsvise resultatet på en simulert mobiltelefon (eller din egen):
Konklusjon
Ved å abstrahere all presentasjonslogikken og stilarkene inn i komponentene kan andre enkelt gjenbruke disse byggeklossene på kryss av alle plattformene. Dette frigjør ressurser og effektiviserer utviklingen.
Fremtind er alltid på utkikk etter de skarpeste. Se hvilke stillinger som er utlyst her eller send en åpen søknad til sbh@fremtind.no om du også får overtenning av innovasjon, IoT og mulighetene datafangst + maskinlæring gir til å forutsi og forebygge.