Vårt delingshjørne
Martin
Klingenberg
26. februar 2021
Jeg digger web-komponenter, men jeg har innsett at ikke alle ser potensialet. Tanken er å lage komponenter løsrevet fra rammeverk, som kan brukes fritt mellom rammeverk. Min teori, er at det er mye skepsis rundt web-komponenter da det er manglende kunnskap om hvordan man skal ta dem i bruk. I teorien kan man bruke en web-komponent hvor som helst, men er det virkelig så enkelt? Jeg har forsøkt å trekke inn en web-komponent inn i et Vue, Angular og React-prosjekt. Konklusjonen, er at det er utrolig lettvindt å bruke web-komponenter uansett hvilket rammeverk du måtte bruke. Se eksemplene under eller dette repoet.
For å teste hvor lett dette er, så har jeg laget en web-komponent. Mine kolleger vil kjenne denne igjen da dette er en kopi av den siste komponenten jeg implementerte på alvtime. Komponenten er ment for å visualisere tilgjengelig overtid og hvilken type overtid samt vise hvor mye overtid man har igjen når man taster inn hvor mye man ønsker å ta ut.
Hvordan lager man web-komponenter?
Man kan lage web-komponenter på mange måter. Man kan lage web-komponenter med vanilla-javascript, men for enkelhetens skyld baserer jeg meg heller på LitElement; et lettvekts rammerverk for å lage web-komponenter. De fleste rammeverk med respekt for seg selv kan generere web-komponenter, så du kan bruke ditt favoritt-rammeverk om det er react, angular eller vue.
Under ser du resultatet samt komponenten implementert med LitElement.
Web-komponenten i action
<script src="https://gist.github.com/klyngen/fec8ca91599ac11939a071791c1b90fc.js"></script>
Hvordan bruker jeg denne magiske komponenten?
Jeg pakket komponenten med tsc og publiserte den på npm. Pakken kan ansaffes med npm install overtime-visualizer
. Så handler det bare om å importere, og binde verdier.
VueJs
Importer komponenten som hvilket som helst annen komponent
Ignorer web-komponenten i main.js / main.ts for at vue ikke skal prøve å resolve komponenten
Når du binder verdier, så må du legge til .prop. Eksempel :overtimeData blir til :overtimeData.prop
Om du skulle ønske å lytte til en event, så bruker du følgende syntax @input="someVueProperty = $event.target.value"
<script src="https://gist.github.com/klyngen/2e8a133ca69a13a9ca7a07209c852606.js"></script>
Angular
I Angular er ting noe enklere
Legg til CUSTOM_ELEMENTS_SCHEMA under schemas for at angular skal akseptere web-komponenter.
<script src="https://gist.github.com/klyngen/490e302a561ab0655960cc8543f4099a.js"></script>
Angular behandler web-komponenter som alle andre komponenter.
Komponenten må importeres der den brukes
Enkelte guides anbefaler at du legger til allowJs: true i tsconfig.json. Det ser ikke ut til å være nødvendig om du bygger og publiserer web-komponenten med typer.
<script src="https://gist.github.com/klyngen/b33295ad760313363d054fb4f5521bd4.js"></script>
React
Jeg kan ikke skryte på meg å ha brukt react i mere enn et par timer. Men det jeg har lært, er at react ikke tar i mot web-komponenter med like åpne armer som Angular og Vue. Jeg fikk komponenten til å fungere med det andre kode-eksemplet under, men når jeg viste dette til en kollega med react-erfaring, så fikk jeg vite at dette ikke er slik man skriver react i dag.
Problemet med react, er at du ikke kan binde properties som ikke er string. Dette er jo langt i fra ideelt, så derfor er det mange der ute som har laget sine egne løsninger på problemet. Det man trenger er en wrapper som konverterer react properties til json-strings.
Løsning 1
Wrap web-komponenten
Bind med state-hooks
Løsning 2
Det man kan si om koden er at den krever ingen endring i konfigurasjon, og man trenger bare å importere komponenten, så er vi good to go.
Importer komponenten med import 'overtime-visualizer'
Bind ved hjelp av Refs
<script src="https://gist.github.com/klyngen/db523833364f05dca8eaf3a2fe290b30.js"></script>
Hvordan er nettleserstøtten?
De aller fleste moderne nettlesere har implementert web-komponent-speccen, men å inkludere polyfills er fortsatt ansett som god praksis. Årsaken er at noen nettlesere fortsatt ikke har implementert hele speccen. Min anbefaling er uansett å styre unna nettlesere som ikke støtter web-komponenter #killInternetExplorer.
Hva sitter jeg igjen med?
Web-komponenter har kommet langt siden jeg implementerte min første polymer 1.0-baserte komponent. På denne tiden var web-komponent-speccen annerledes, og jeg minnes om frustrerte timer der jeg ikke forstod hvorfor komponenten lastet med html-imports ikke dukket opp i DOM'en.
Nå er verden en helt annen. Nå som web-komponent-speccen har kommet til versjon 1, så ser jeg en klar fremtid for teknologien. Det er faktisk slik at stort sett alle frontend-rammeverk har god støtte for web-komponenter. Det er bare React som henger etter (https://custom-elements-everywhere.com/). Etter å ha snoket litt i issues på React sin github-side, så ser jeg for meg at React 18, er den versjonen som introduserer god web-komponent støtte. Og når den tid kommer, så ser jeg ingen grunn til å ikke favne om web-komponenter.
Lenker
Kode skrevet for artikkelen: https://github.com/klyngen/webcomponents-examples
Anbefaler å se igennom web-komponent-støtten du finner her: https://custom-elements-everywhere.com/