Angular Ivy repræsenterer en grundlæggende intern omskrivning af Angular-kompilatoren, runtime og dele af frameworket, hvilket muliggør mere effektiv komponentudvikling og hurtigere, mindre bundter gennem Ahead-of-Time (AOT) kompilering. En af de centrale forbedringer i Ivy er muligheden for metadata-arv mellem komponentklasser, som nu foregår på en forudsigelig og elegant måde. Dette betyder, at en komponent kan arve både funktionalitet og tilhørende metadata såsom input-egenskaber, event bindings og styling fra en basekomponent uden behov for gentagelse eller ekstra konstruktorer i underklasser.
For eksempel kan en komponent som SuggestedSearchComponent udvide en BaseSearchComponent, og samtidig arve en placeholder-input og en onSearch-eventbinding. Samtidig tilføjer den nye input-egenskaber som en liste over forslag, der dynamisk rendres i brugergrænsefladen. Denne arv og genbrug af metadata gør komponentudvikling mere modulær og vedligeholdelsesvenlig.
Ivy introducerer en ny instruktionssæt til runtime, der effektivt oversætter Angular-komponenter til DOM-opdateringer ved hjælp af to separate instruktioner: én til initialisering og én til opdatering ved ændringer. Denne tilgang er lettere og mere effektiv end den tidligere View Engine, hvor større applikationer kunne ende med tungere AOT-bundter end just-in-time (JIT) bundter. Med Ivy er både bundtstørrelse og ydelse forbedret markant, ikke mindst fordi dele af runtime kan tree-shakes, så kun nødvendige funktioner inkluderes i output.
Den praktiske konsekvens af Ivy’s design betyder også, at små applikationer ikke længere lider under større AOT-bundter, og mikrofrontend- eller webkomponent-arkitekturer kan drage fordel af minimal overhead. Samtidig er bagudkompatibilitet opretholdt ved hjælp af Angular Compatibility Compiler (ngcc), som transformerer View Engine-kompilerede biblioteker til Ivy-kompatible, selvom dette medfører en øget initial byggetid.
Fra Angular 12 anbefales biblioteker at levere delvist Ivy-kompilerede bundter, hvilket muliggør hurtigere inkrementelle builds baseret på lokalitetsprincippet, hvor kompileren kun behøver at kende til offentlige API’er frem for hele komponenthierarkiets afhængigheder. Denne forfinelse af kompilationsprocessen reducerer generelt byggetider og øger udviklerproduktiviteten.
En anden væsentlig forbedring i Angular Ivy er udvidelsen af konfigurationsmuligheder, specielt med introduktionen af strict mode som standard ved oprettelse af nye projekter. Denne tilstand aktiverer en række TypeScript-kompilatorindstillinger, der fremmer tidlig fejlfinding og øger kodekvaliteten gennem strengere typer og konsekvente regler, hvilket igen bidrager til sikrere og mere pålidelige applikationer.
Det er vigtigt at forstå, at AOT-kompilering ikke blot handler om at gøre produktionen hurtigere, men også om at fjerne forskelle mellem udvikling, test og produktion. Med Ivy kan AOT anvendes gennem hele udviklingscyklussen, hvilket sikrer mere forudsigelighed og færre overraskelser i runtime.
Det understreges også, at man ikke behøver dyb indsigt i Angular-kompilatorens interne mekanismer for at drage fordel af Ivy. Fokus bør være på at anvende de nye værktøjer og konfigurationer, som frameworket stiller til rådighed for at optimere både bundtstørrelse og udviklingstid. Fortsat opmærksomhed på kompatibilitet, især når man arbejder med tredjepartsbiblioteker, er dog afgørende for at undgå problemer i byggeprocessen.
Foruden de tekniske aspekter ved Ivy-kompilering er det vigtigt for læseren at have en grundlæggende forståelse af objektorienterede principper i TypeScript, især arv og metadata, da Angular’s komponentarkitektur i høj grad bygger på disse. En dybere indsigt i TypeScripts strenge typer og deres indvirkning på Angular-kode kan yderligere forbedre kodekvaliteten og reducere runtime-fejl.
Endelig bør man være bevidst om, at Ivy ikke blot er en compiler-ændring, men en helhedsorienteret forbedring af Angulars måde at bygge, pakke og optimere applikationer på. Det åbner op for nye muligheder i modulopbygning, lazy loading, mikrofrontend-arkitektur og mere, og derfor bør udviklere løbende holde sig opdateret om Angulars udvikling og best practices inden for disse områder.
Hvordan vises kursusvideoer og skoler med Angular-komponenter?
Et centralt aspekt i moderne Angular-applikationer er evnen til at præsentere dynamisk indhold på en måde, der er både komponentiseret og effektiv. Når vi arbejder med kursusvideoer, er det naturligt at lade præsentationen ske gennem en dedikeret komponent, der integrerer med YouTube Player-API'et og dermed tillader afspilning direkte i applikationen. Video-komponenten modtager dens data gennem @Input bindings: titel, navn, video-ID, beskrivelse og et kort uddrag. Disse data bruges til at konstruere både den visuelle præsentation og den direkte link-adgang til videoen på YouTube.
Selve initialiseringen af YouTube-afspilleren gøres ved programmatisk at tilføje det nødvendige script til dokumentets <body> i ngOnInit(), og rydde op i ngOnDestroy(). Denne tilgang sikrer, at vi ikke efterlader inaktive eller overflødige DOM-elementer, når komponenten fjernes. En velovervejet tilgang, der sikrer bedre ydelse og undgår potentielle lækager.
I templaten til Video-komponenten integreres cdkCopyToClipboard, hvilket giver brugeren mulighed for nemt at kopiere YouTube-linket til udklipsholderen. Denne funktion, mens subtil, tilføjer betydelig brugervenlighed, særligt i desktop-scenarier, hvor deling af ressourcer er en væsentlig del af arbejdsflowet.
En bemærkelsesværdig detalje i præsentationen af videoerne er brugen af tidligere definerede CSS-egenskaber som videoSize, der allerede er optimeret gennem det visuelle grid-system. Det demonstrerer værdien af konsistent og genanvendelig stilarkitektur i Angular-applikationer. Samtidig udnytter komponenten Angular-temaets tile-farver gennem klassebaseret manipulation, hvilket harmoniserer brugeroplevelsen visuelt.
Når kursuskomponenten integrerer Video-komponenten, benyttes async pipe til at håndtere asynkrone datastrømme. Det sikrer, at videopræsentationen først initialiseres, når dataene er tilgængelige, og undgår dermed race conditions eller visning af ufuldstændig information.
Ud over videovisningen demonstreres integrationen af Angular Google Maps-komponenten i Schools-komponenten. Her kan brugeren finde skoler geografisk repræsenteret som markører på et kort. Ved klik på en markør åbnes en MapInfoWindow, som indeholder link til de kurser skolen udbyder. Dette illustrerer en sømløs overgang fra geografisk navigation til indholdsbaseret navigation i applikationen.
Selve Schools-komponenten henter data fra en SchoolsService, som leverer en Observable. Brugen af async pipe i kombination med NgIf i templaten sikrer, at komponenten håndterer dataens asynkrone natur elegant. Når en skole vælges, vises dens information i MapInfoWindow, og ved klik på et kursus overføres brugeren til kursuskomponenten med et id-parameter. Dette parameter bruges til at hente kursusdata og vise relevant videoindhold.
Routingstrukturen i applikationen er opsat til at håndtere course/:id, hvilket muliggør direkte navigation via ID'er og dermed giver mulighed for dybe links og bogmærkning. I den beskrevne implementering antages det, at brugeren kun har adgang til ét kursus ad gangen – en forenkling, der tjener demonstrationen, men som i virkelige scenarier bør udvides med brugersessioner og loginlogik. Denne logik introduceres senere i projektet, hvor flere scopes og providers tages i brug for at håndtere autentifikation og brugerens valgte kurser.
Det er vigtigt, at læseren forstår, hvordan Angulars komponentbaserede arkitektur muliggør høj sammenhængskraft mellem visning og data, samtidig med at løs kobling mellem komponenter opretholdes. Brug af Angulars Observables, async pipe, input binding, samt integration med tredjeparts-API’er som YouTube og Google Maps, er centrale kompetencer i enhver kompleks Angular-applikation. Disse eksempler viser, hvordan interaktive og responsive brugergrænseflader kan bygges uden at miste struktur eller modularitet i kodebasen.
Hvordan tester man Angular-komponenter uden at binde sig til DOM-strukturen?
Når man udvikler og tester brugerflader i Angular, er det ofte svært at undgå en tæt kobling mellem testen og DOM-strukturen. Dette fører til skrøbelige tests, der let brydes, når UI ændres, selv uden at funktionaliteten ændres. Angular Ivy introducerer et mere elegant alternativ: komponenttest-harnesses. Disse udnytter det velkendte Page Object-mønster, men anvender det mere granulært og målrettet direkte på komponentniveau. Angular Material tilbyder allerede et bibliotek af færdige harnesses, som dramatisk reducerer behovet for direkte DOM-manipulation under test.
Et konkret eksempel er test af en temakomponent, hvor brugeren kan vælge farve og størrelse til forskellige UI-elementer. Ved hjælp af MatInputHarness er det muligt at simulere en bruger, der vælger en ny farve til baggrunden af et header-element. I stedet for at hente DOM-elementet direkte og udlæse dets værdi, kaldes getValue()-metoden på harnessen, som repræsenterer input-feltet semantisk.
Denne test sikrer, at standardværdien er sat korrekt. Når værdien ændres, sker det gennem en metode på harnessen – ikke via manuel DOM-manipulation. Harnessen sørger for at integrere med Angulars change detection automatisk.
Ved at undgå fixture.detectChanges() reduceres testens kompleksitet og vedligeholdelsesomkostninger. Testen simulerer brugerens interaktion på et højere abstraktionsniveau.
Samme tilgang gælder for mere avancerede komponenter som sliders. For eksempel ved test af en videosize-slider, hvor værdien valideres uden eksplicit DOM-arbejde:
Her kobles testen direkte til den funktionelle værdi fremfor DOM’en, hvilket gør testen mindre følsom over for ændringer i komponentens struktur.
I tilfælde, hvor komponenter består af flere lag – f.eks. en Course-komponent, der indeholder en Video-komponent, som igen indeholder en YouTubePlayer – bliver behovet for egne harnesses tydeligt. Her kan man bygge en VideoHarness, som afspejler komponentens adfærd uden at eksponere dens interne DOM.
Dette harness giver en struktureret og genanvendelig måde at tilgå data, som ellers skulle være testet gennem komplekse DOM-operationer. Det beskytter også testen mod ændringer i markup, idet logikken nu er indkapslet i metoder som getText() og textEquals().
Test af renderede videoer kan derefter struktureres som følger:
Her matches indholdet i video-komponenten med data fra service-laget. Bemærk, at textEquals() kommer fra harnessen, hvilket tillader fleksibilitet og abstraktion. Ved at uddelegere sammenligningslogikken til harnessen, opnår vi løs kobling og bedre testbarhed.
Det næste logiske skridt er at oprette et særskilt harness for YouTubePlayer, som inkapsler afhængigheden til det underliggende DOM-element og eksponerer en metode til at hente video-id:
Denne struktur gør det muligt at teste Course-komponenten uden at kende detaljerne i YouTubePlayer-implementeringen. Resultatet er en række testkomponenter, der efterlever principper om isolation, lav kobling og høj genbrugelighed. Testen bliver en afspejling af brugerens adfærd, ikke en teknisk gennemgang af DOM’en.
At benytte test-harnesses i Angular skaber mere vedvarende tests og tillader, at testene udvikler sig parallelt med komponenterne – uden at bryde under mindre ændringer i markup. Det er essentielt at forstå, at harnesses er mere end syntaktisk sukker; de er en strukturel nødvendighed for vedligeholdbare frontend-tests i moderne Angular-udvikling.
Hvordan anvender man Angular Compatibility Compiler effektivt i moderne udviklingsmiljøer?
Angular Linker har overtaget rollen fra Angular Compatibility Compiler (ngcc) og fungerer som et overgangsværktøj, der konverterer delvist Ivy-kompilerede biblioteker til fuldt Ivy-kompilerede biblioteker, før de inkluderes i applikationens samlede kompilering. Dette trin bliver essentielt i nyere versioner af Angular, hvor understøttelsen for Angular Compatibility Compiler fjernes fuldstændigt. Når denne ændring er fuldt implementeret, vil kun delvist Ivy-kompilerede biblioteker kunne anvendes. Derfor bliver forståelsen og korrekt anvendelse af ngcc fortsat vigtig i overgangsperioden.
Tidligere versioner af Angular 9 krævede manuel kørsel af ngcc før enhver form for udviklingsarbejde – om det var opstart af udviklingsserver, testkørsel eller kompilering. Senere versioner forbedrede denne arbejdsgang ved at lade Angular CLI selv trigge ngcc, når nødvendigt. Alligevel forbliver det muligt og i mange tilfælde hensigtsmæssigt at udføre manuel kørsel af ngcc, da det giver bedre kontrol og mulighed for at optimere kompileringstiden. Hver gang en ny version af et Angular-bibliotek installeres – eller et nyt bibliotek tilføjes – bør ngcc køres igen.
En anbefalet praksis er at tilføje ngcc-kommandoen som en del af dit postinstall-hook i package.json. Dette automatiserer processen og sikrer, at kompilering udføres straks efter installation af afhængigheder, uden at forsinke opstarten af udviklings- eller build-processen. Under kørslen af ngcc er det desuden muligt at arbejde videre med kildekoden uden afbrydelse.
Standardkommandoen til manuel kørsel bør inkludere parametre, der maksimerer effektiviteten:
Med --first-only kompileres kun det første genkendte modulformat, hvilket reducerer kompileringstiden. --properties angiver i hvilken rækkefølge formattyperne forsøges kompileret; her prioriteres es2015, som generelt giver hurtigste resultat. --create-ivy-entry-points sørger for, at nye Ivy-kompilerede filer placeres i en separat undermappe (__ivy_ngcc_), hvilket er hurtigere end at overskrive de eksisterende View Engine-filer.
I versioner som 9.0 og 11.1 af Angular bør man dog overveje at udelade --create-ivy-entry-points, da in-place-kompilering kan være marginalt hurtigere i disse specifikke versioner. En anden vigtig mulighed er --use-program-dependencies, som målretter kompilering til kun de pakker, der faktisk anvendes i projektets kildekode. Dette er især fordelagtigt ved brug af Angular CDK og Angular Material, hvor hver eneste underpakke som standard ellers kompileres – også de ubrugte – hvilket har stor negativ indvirkning på hastigheden.
Til endnu mere målrettet kompilering kan --target bruges til at angive et enkelt specifikt bibliotek, og --tsconfig sammen med --use-program-dependencies kan anvendes til at rette fokus mod bestemte projekter i et workspace. Disse kombinationer muliggør et ekstremt fokuseret og hurtigt kompileringstrin i større projekter.
I CI/CD-miljøer, hvor node_modules typisk ikke caches fuldt, anbefales det at køre ngcc som separat trin for at sikre ren og forudsigelig kompilering. En effektiv strategi indebærer at bruge samme parametre som i det lokale miljø og placere kommandoen i postinstall-scriptet. Dette tillader optimal kontrol og samtidig separation af kildekode og kompilering, hvilket også forenkler fejlsøgning og build-debugging.
Det er væsentligt at forstå, at ngcc-modificerede filer altid placeres i node_modules, hvilket betyder, at enhver ændring i afhængigheder – selv den mindste – kræver ny kørsel af kompilatoren. Et automatiseret setup med dedikerede scripts og korrekt cache management i CI-pipelines bliver derfor kritisk, især i større applikationer med hyppige afhængighedsopdateringer.
Endvidere bør man være opmærksom på, at selvom ngcc er i færd med at blive udfaset, er det stadig et kerneværktøj i miljøer, hvor ikke alle biblioteker endnu er fuldt overført til Ivy. Det betyder, at en dyb forståelse for dets virkemåde og integration i både lokale og automatiserede workflows fortsat er afgørende for problemfri Angular-udvikling.
Det er også vigtigt at have klart overblik over versionsafhængigheder og deres
Hvordan forstår man fuglelivets dynamik i forskellige årstider?
Hvordan vi kan definere den inverse funktion med Klassisk Valg i Lean
Hvad betød det at være mellem to verdener i 1200-tallets Palermo?
Hvordan den tragiske hændelse med Batavia påvirkede den hollandske ekspansion i Asien

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский