S příchodem Ivy se Angular dramaticky proměnil – ačkoliv většina vývojářů ho vnímá jen jako neviditelný posun v pozadí, jeho dopady sahají hluboko do každodenního vývoje. Ivy není pouze nový rendering engine. Je to kompletní přehodnocení toho, jak Angular pracuje s komponentami, šablonami, závislostmi a jak celý ekosystém reaguje na změny.

Ivy zvyšuje rychlost buildů, zmenšuje velikost bundlů a nabízí výrazně lepší možnosti pro debugování. Mnoho vývojářů si všímá především nižší latence při AOT (Ahead-Of-Time) kompilaci, ale klíčovým přínosem je také podpora tzv. locality – každá komponenta je kompilována izolovaně, což nejenže zrychluje proces sestavení, ale zjednodušuje testování a refaktoring.

Zatímco předchozí verze Angularu vyžadovaly komplexní metadata a centralizované sestavení, Ivy umožňuje modulární přístup. Komponenty lze sestavovat nezávisle na kontextu aplikace a jejich výstupem je efektivnější kód, který přesně reflektuje to, co komponenta dělá – bez zbytečných závislostí.

Další zásadní výhodou je schopnost Ivy poskytnout runtime API pro inspekci komponent. To mění způsob, jak přistupujeme k ladění. Vývojář má možnost za běhu aplikace zkoumat strom komponent, jejich stav, vstupy i výstupy, a dokonce i vnořené kontexty embedded views. Co bylo dříve možné pouze s pomocí neformálních nástrojů nebo vnitřního API, je nyní oficiálně podporováno a stabilní.

Také testování komponent s příchodem Ivy prochází evolucí. V kombinaci s TestBed.inject a přísnější kontrolou typů v šablonách je možné psát testy, které jsou nejen robustní, ale i výstižnější. Vývojáři jsou schopni přesněji definovat závislosti a očekávání testovaných entit, což posiluje konzistenci a udržitelnost kódu.

Ivy také podporuje lazy loading dat podle lokalizace, což je klíčové při budování aplikací s globálním dosahem. Díky novým globalizačním API lze dynamicky měnit jazyk i směr zobrazení (dir atribut) podle kulturního kontextu uživatele, aniž by to negativně ovlivnilo výkon nebo velikost výstupního balíčku.

V oblasti vizuální prezentace se Angular posunul směrem k využití moderních webových technologií jako CSS custom properties. Ty lze nyní bez potíží používat i v rámci komponent a Angular umožňuje jejich dynamické přepínání, například pro změnu tématu aplikace. To vše bez nutnosti re-renderingu nebo ruční manipulace s DOM.

Ivy také redefinuje možnosti DI (dependency injection) skrze nové tzv. provider scopes. Například any scope umožňuje, aby každá lazy-loaded část aplikace měla svou vlastní instanci služby, čímž se předchází nečekanému sdílení stavu napříč různými moduly. platform scope zase umožňuje sdílení stavu mezi zcela nezávislými Angular aplikacemi běžícími ve stejném prostředí – například v mikrofrontend architekturách.

Zásadní posun Ivy přináší v tom, jak Angular přistupuje k aktualizacím. Díky přesnější analýze změn na úrovni jednotlivých komponent a optimalizované kompilaci je aktualizace projektu na novou verzi frameworku nejen rychlejší, ale i bezpečnější. Menší a lépe izolované změny znamenají menší riziko regresí a lepší předvídatelnost chování aplikace po upgradu.

Díky těmto vlastnostem není Ivy jen technologickým vylepšením – představuje základ pro novou generaci Angular aplikací, které jsou rychlejší, více modulární, lépe testovatelné a přizpůsobitelné moderním potřebám vývoje.

Je důležité pochopit, že Ivy není jen pro velké enterprise aplikace – i menší projekty těží z jeho výhod. Mnoho z těchto zlepšení probíhá pod povrchem, ale ovlivňuje každodenní práci vývojáře. Ivy není volitelná nadstavba, je to nový základ, na kterém Angular staví svou budoucnost.

Vývojáři by měli věnovat zvláštní pozornost nové syntaxi, jako je optional chaining a nullish coalescing, které spolu s Ivy vytvářejí čistší a bezpečnější kód. Zároveň je nezbytné porozumět novým způsobům testování komponent pomocí component harnessů – nástroje, které oddělují testování chování od detailů implementace a činí testy stabilnějšími i při změně UI.

Ve světle těchto změn je nutné přistupovat k učení Ivy nejen jako k technické nutnosti, ale jako k příležitosti přehodnotit a zlepšit způsob, jakým stavíme webové aplikace.

Jak efektivně používat nové Ivy API pro ladění aplikací Angular

V aplikacích postavených na frameworku Angular se ladění stalo nedílnou součástí vývojového procesu. Od verze Angular Ivy byly představeny nové API pro ladění, které nahrazují starší NgProbe API. Tato nová sada funkcí, dostupná pouze v režimu vývoje, poskytuje nástroje pro inspekci komponent, událostí a kontextů zobrazených prvků na úrovni DOM. Tyto nástroje značně usnadňují ověřování předpokladů o aktivních komponentách, jejich šablonách a vazbách DOM během běhu aplikace.

Jedním z nejdůležitějších přínosů těchto funkcí je možnost hlubší interakce s jednotlivými součástmi aplikace. To znamená, že nyní můžeme sledovat a ovládat různé aspekty aplikace přímo v běhu, což je užitečné zejména při komplexních aplikacích s mnoha interakcemi mezi komponentami. Nové API umožňuje například přístup k metadatům komponent nebo direktiv, což bylo dříve složitější a vyžadovalo externí nástroje. Tento přístup je nejen efektivní, ale také flexibilní a přizpůsobitelný pro různé scénáře.

Jednou z klíčových funkcí je ng.applyChanges, která označuje komponentu pro "kontrolu špinavých" dat, což je zvláště užitečné při používání strategie detekce změn OnPush. Tato funkce spustí cyklus detekce změn, což umožňuje aktualizovat uživatelské rozhraní, když se změní data komponenty, aniž by bylo nutné manuálně vyvolávat znovu vykreslení. Tato schopnost je velmi důležitá při ladění aplikací s komplexními datovými strukturami, kde se změny nemusí automaticky projevovat ve všech částech aplikace.

Další funkcí je ng.getComponent, která nám umožňuje získat referenci na komponentu připojenou k určitému DOM prvku. To je velmi užitečné, když chceme zjistit, která komponenta je zodpovědná za vykreslování určitého prvku na stránce, což nám pomáhá lépe pochopit strukturu aplikace a optimalizovat její výkon. Podobně ng.getContext nám poskytuje přístup ke kontextu zobrazené komponenty, což je nezbytné pro inspekci struktur, které jsou výsledkem strukturálních direktiv jako NgIf nebo NgFor.

Další užitečné funkce zahrnují ng.getListeners, která nám umožňuje zjistit, jaké posluchače událostí jsou připojeny k určitému DOM elementu. To zahrnuje i posluchače, které nejsou přidány přímo pomocí Angularu, což nám poskytuje širší obraz o tom, jaké interakce v aplikaci probíhají. ng.getOwningComponent nám zase umožňuje zjistit, která komponenta je zodpovědná za konkrétní prvek nebo direktivu, což je užitečné při analýze a ladění komplexních interakcí mezi komponentami a jejich hostiteli.

Dále je důležité si uvědomit, že nové API pracuje s různými datovými strukturami, jako jsou metadata komponent nebo direktiv. Tyto struktury nám poskytují podrobnosti o vstupech a výstupech, které jsou propojeny mezi komponentami a jejich šablonami. Ačkoliv mohou tyto informace být na první pohled složité, jejich správné pochopení nám umožní hlubší analýzu a ladění aplikací. Metadata obsahují důležité informace o detekci změn, zapouzdření a dalších aspektech komponenty.

Jako příklad, ng.getDirectiveMetadata nám umožňuje získat metadata o konkrétní komponentě nebo direktivě, včetně informací o vstupech a výstupech. Tato data jsou obzvlášť důležitá při ladění aplikací, kde se často mění dynamicky propojené komponenty a jejich stavy. Metody jako ng.getDirectives a ng.getHostElement zase umožňují získat přehled o připojených direktivách a hostitelských prvcích, což je nezbytné pro správnou interpretaci DOM struktury aplikace.

Důležité je také pochopit, že runtime ladicí API v Ivy umožňuje hluboký vhled do dynamických aspektů aplikace, ale je k dispozici pouze v režimu vývoje. To znamená, že tyto nástroje jsou určeny pro použití při vývoji a testování aplikace, nikoliv pro produkční prostředí. Při přechodu na produkci je třeba mít na paměti, že některé ladicí nástroje mohou ovlivnit výkon aplikace, proto by měly být deaktivovány.

V souhrnu nové Ivy API přináší mnohé výhody při ladění a inspekci Angular aplikací. Využití těchto nástrojů výrazně zjednodušuje vývojový proces a umožňuje rychlejší a přesnější odhalování problémů. Pochopení a efektivní využívání těchto funkcí vám umožní optimalizovat aplikace a přizpůsobit je specifickým potřebám uživatelů.

Jak efektivně využívat příkaz ng update pro migraci Angular aplikace

Migrace Angular aplikací, zejména při přechodu z View Engine na Ivy, může být složitý proces, který vyžaduje detailní pochopení správy závislostí a efektivní využití nástrojů, jako je příkaz ng update. Tento příkaz je klíčový pro správu verzí a migrace Angular frameworku a třetích stran, přičemž podporuje jak automatizované, tak ruční migrace.

V rámci migrace je nezbytné správně řídit závislosti mimo oficiální Angular balíčky. Mezi hlavní závislosti, které Angular spravuje, patří RxJS, tslib a Zone.js. Tyto závislosti jsou obvykle řízeny procesem aktualizace Angularu, ale některé migrace pro závažné změny mohou být nepravidelně dostupné. Například migrace pro RxJS mezi verzemi 6.x a 7.x nejsou plánovány, což může být problém, pokud aplikace závisí na konkrétní verzi této knihovny.

Zone.js, která je stále v předběžné verzi, může být dalším zdrojem problémů, jelikož každá menší verze obsahuje změny, které mohou ovlivnit funkčnost aplikace. Většina aplikací však tuto knihovnu nepoužívá přímo, protože její funkcionalitu obvykle zabalí API NgZone. Přesto při importu Zone.js do aplikace může být nutné upravit cesty importů, což může být automatizováno migrací Angularu 11.

TypeScript, který nefunguje podle pravidel semantického verzování, rovněž přináší výzvy při migracích, protože každá menší verze může obsahovat změny, které způsobí chyby při kompilaci. Pro tyto případy je nezbytné nahlížet do oficiálních blogových příspěvků, které detailně popisují změny a nutné kroky pro opravu chyb.

Automatizované migrace, které Angular CLI nabízí, mohou výrazně usnadnit přechod na novější verze frameworku, ale je důležité věnovat pozornost několika klíčovým aspektům těchto migrací. Příkaz ng update umožňuje aktualizaci Angular specifických balíčků i třetích stran, a to včetně provádění příslušných migrací. Příklad základního příkazu pro aktualizaci Angularu je následující:

sql
ng update @angular/cli @angular/core

Tento příkaz aktualizuje hlavní balíčky Angular frameworku na nejnovější verzi a zároveň provede potřebné automatizované migrace. Je také možné aktualizovat jednotlivé verze, například pro verzi 9 Angularu, použijte:

sql
ng update @angular/cli^9 @angular/core^9

Tento přístup je doporučený, protože aktualizace probíhá po jednotlivých verzích, což usnadňuje správu migrací a umožňuje lepší sledování změn mezi verzemi. Důležitou funkcí je také parametr --create-commits, který umožňuje vytváření commitů pro každou migraci, což následně zjednodušuje revizi změn a umožňuje jejich selektivní použití nebo revertování.

Například pokud chcete provést migraci pouze pro určitou změnu, jako je nastavení výchozího buildování pro produkci, můžete použít příkaz:

kotlin
ng update @angular/cli@^12 --migrate-only production-by-default

Automatizované migrace, které Angular CLI nabízí, zahrnují i různé drobné, ale důležité změny v konfiguracích. Jednou z takových migrací je migrace workspace-version-9, která přepíná volbu aot na true i v základní vývojové konfiguraci, čímž zajišťuje, že aplikace bude kompilována s Ahead-of-Time (AOT) překladačem, což přináší výhody v podobě rychlejšího spuštění aplikace.

Další důležitou migrací je změna syntaxe pro lazy loading, která přechází ze staré formy s použitím řetězce k dynamickým importům. To je nezbytné pro zajištění kompatibility s novějšími verzemi Angularu, kde je tato syntaxe považována za zastaralou a neoptimální.

Ve verzi 9 Angularu byla také přidána možnost volitelných statických dotazů pro ViewChild a ContentChild, což umožňuje optimalizovat chování aplikace, zejména při práci s dynamickými daty a komponentami. V rámci migrace se doporučuje, aby byl parametr static explicitně nastaven na true, pokud je to potřeba.

Příkaz ng update tak umožňuje nejen provádění automatických migrací, ale také poskytuje kontrolu nad tím, jak a kdy tyto migrace probíhají. Kromě toho je třeba mít na paměti, že některé migrace mohou vyžadovat ruční zásah, což znamená, že automatizovaný proces není vždy dostatečný. Pro aplikace, které používají specifické knihovny nebo pokročilé konfigurace, je vždy nutné věnovat pozornost doporučením a postupům v oficiální dokumentaci Angularu, které podrobně popisují konkrétní kroky a důvody pro změny.

V závěru je důležité si uvědomit, že aktualizace Angularu je dynamický a mnohdy komplikovaný proces, který vyžaduje pečlivý přístup k závislostem, konfiguracím a migracím. Používání příkazu ng update a správné sledování všech doporučených postupů a migrací je klíčem k úspěšné a bezproblémové migraci aplikace na novější verze Angularu.

Jak překonat omezení kompilace v předstihu v Angularu

Jedním z největších pokroků, které přinesla nová verze frameworku Angular, je kompilace v předstihu (Ahead-of-Time, AOT). Tento přístup nabízí výrazné zrychlení doby načítání aplikací a snížení velikosti finálního balíčku, protože veškeré kompilování kódu se provádí již při sestavení aplikace, nikoli až při jejím spuštění. Nicméně, i přestože tento způsob kompilace přináší mnoho výhod, existují určitá omezení, na která je třeba si dát pozor.

Jedním z hlavních vylepšení je způsob, jakým se kompilují šablony komponent. V rámci kompilace v předstihu Angular vytváří specifické instrukce, které jsou přímo vykonatelné, což zaručuje rychlejší běh aplikace. Na rozdíl od předchozího přístupu s View Engine, kdy byly data struktury interpretovány za běhu, Ivy instrukce jsou okamžitě vykonatelné. To vede k podstatnému zrychlení vykreslování a interakce s DOM.

Pokud používáme AOT kompilátor, doporučuje se zapnout přísné ověřování typů šablon. Toto ověření zachycuje většinu chyb v typech, které se mohou objevit v Angular metadatech, modelech komponent nebo šablonách komponent. Díky tomu se tyto chyby objeví buď během sestavení aplikace, nebo přímo v editoru kódu při použití Angular Language Service, což usnadňuje vývoj. Bez tohoto ověření by podobné chyby mohly vést k problémům až při samotném běhu aplikace, což by mohlo být frustrující.

Pokud jde o jednotkové testy, kompilace v předstihu má také pozitivní vliv na rychlost. Angular Ivy značně zrychluje jak čas sestavení, tak i opětovného sestavení, což je přínosem nejen pro samotný vývojový server, ale i pro běh testů. Kromě toho zavádí Angular Ivy kompilovací cache, díky níž jsou již kompilované moduly, komponenty, direktivy, pipe a služby uchovávány mezi jednotlivými testy. Tato funkce je v předchozím View Engine systému nedostupná.

Další výhodou je, že při použití AOT kompilace se aplikace načítá rychleji, protože samotný kompilátor není součástí balíčku aplikace, což vede k rychlejšímu spuštění. Ivy runtime je výrazně rychlejší než View Engine, protože Ivy instrukce jsou přímo vykonatelné, zatímco View Engine musel interpretovat struktury dat šablony před tím, než mohl začít pracovat s DOM.

Pokud však využíváme kompilaci v předstihu, musíme být připraveni na některé její limity. Například direktivy, komponenty a pipe nemohou být dynamicky vytvářeny na základě runtime informací. Kompilace v předstihu totiž očekává, že všechny deklarace budou známé již při sestavování aplikace, což omezuje možnosti dynamického přizpůsobení na základě serverových nebo statických konfigurací. Kdybychom chtěli tuto funkcionalitu zachovat, museli bychom do aplikace zahrnout samotný kompilátor Angular a použít jej i během běhu aplikace, což by ale zbytečně zvyšovalo velikost balíčku a ztížilo by načítání.

Naštěstí existuje možnost, jak obejít některé z těchto omezení. Například, pokud potřebujeme hodnoty, které jsou určeny asynchronně, musíme je obalit do služby nebo funkce, která vrací Promise nebo Observable. S tímto přístupem je možné efektivně pracovat s asynchronními daty i v rámci kompilace v předstihu.

Pokud jde o deklarování metadat, Angular přísně omezuje použití funkcí a statických metod pro určování deklarací jako jsou imports nebo declarations modulu. Funkce používané pro tuto deklaraci musí vracet pouze jednu hodnotu, jinak kompilace selže. Tento problém lze řešit tím, že refaktorujeme funkce tak, aby vrátily pouze jediný výraz, například pomocí ternárního operátoru.

Jedním z konkrétních příkladů, kdy se setkáváme s těmito omezeními, je situace, kdy chceme dynamicky určovat, který komponent bude na začátku aplikace zobrazen. Při použití funkcí pro dynamické určování těchto komponent dojde k chybě kompilace v předstihu. Řešením je zjednodušení těchto funkcí tak, aby obsahovaly pouze jeden návratový příkaz.

Dalším omezením je nepodporování tzv. tagged template literals ve šablonách komponent. Pokud chceme vytvořit dynamickou část šablony, která používá takovou konstrukci, dojde při kompilaci v předstihu k chybě. Namísto toho doporučujeme použít běžnou funkci pro generování dynamických částí šablon.

Přes všechna tato omezení přináší kompilace v předstihu značné výhody v podobě rychlejšího vykonání aplikace a menšího balíčku, což je obzvlášť důležité v produkčních verzích aplikací. Při práci s Angular Ivy tedy stojí za to zvážit tato omezení a správně je obejít, aby bylo dosaženo co nejefektivnějšího využití kompilace v předstihu.

Jak optimalizovat regionální podporu pomocí vylepšených globalizačních API v aplikacích Angular?

V současné době je podpora různých jazyků a regionů v aplikacích nezbytným aspektem při vytváření aplikací, které mají globální dosah. Výzvou je nejen překlad textů, ale i přizpůsobení vizuálních prvků a chování aplikace podle specifických regionálních potřeb, jako je směr textu (odleva doprava nebo zprava doleva) nebo jazyková nastavení. V tomto kontextu přichází na řadu práce s globalizačními API a vytváření dynamických komponent, které automaticky reagují na změny v těchto parametrech.

V Angular aplikacích můžeme optimalizovat podporu různých regionů a jazyků, pokud použijeme efektivní přístup k manipulaci s atributy, jako je dir (směr textu) na kořenovém elementu aplikace. Jak toho dosáhnout, je ukázáno v následujícím příkladu, kde se používá služba, která dynamicky nastavuje hodnotu atributu dir na kořenovém elementu aplikace.

Vzhledem k tomu, že nemůžeme použít direktivu přímo na kořenovou komponentu, je potřeba vytvořit službu, kterou můžeme injektovat do kořenové komponenty. Tato služba bude mít na starosti inicializaci efektů na začátku běhu aplikace, jak je ukázáno v následujícím kódu:

typescript
import { Component } from '@angular/core';
import { HostDirectionService } from './shared/ui/host-direction.service'; @Component({ selector: 'app-root', template: '', viewProviders: [HostDirectionService], }) export class AppComponent { constructor(hostDirection: HostDirectionService) {} }

Tato komponenta používá službu HostDirectionService, která je zodpovědná za správu směru textu aplikace podle aktuálního jazykového nastavení (locale). Služba HostDirectionService obsahuje observabilní vlastnost, která se aktualizuje při změně lokalizace, a používá Renderer2 pro nastavení hodnoty atributu dir na správný směr.

typescript
import { Direction } from '@angular/cdk/bidi'; import { getLocaleDirection } from '@angular/common'; import { ElementRef, Injectable, OnDestroy, Renderer2 } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators'; @Injectable() export class HostDirectionService implements OnDestroy { #destroy = new Subject(); #direction$: Observable<Direction> = this.localeState.locale$.pipe( map((locale) => getLocaleDirection(locale)) ); constructor( private localeState: LocaleStateService, private host: ElementRef, private renderer: Renderer2 ) { this.#direction$ .pipe(takeUntil(this.#destroy))
.subscribe((direction) => this.setHostDirection(direction));
}
ngOnDestroy(): void { this.#destroy.next(); this.#destroy.complete(); } private setHostDirection(direction: Direction): void { this.renderer.setAttribute(this.host.nativeElement, 'dir', direction); } }

Díky této službě můžeme efektivně reagovat na změny lokalizace a měnit směr textu, což je zvláště důležité pro jazyky, které používají opačný směr zápisu než latinština (např. arabština nebo hebrejština).

Další zajímavou funkcí, kterou můžeme implementovat, je podmíněné načítání médií na základě směru textu. Ve chvíli, kdy aplikace detekuje směrování jazyka, může se rozhodnout, jaký obraz nebo mediální obsah načíst podle tohoto směru. To lze dosáhnout pomocí podobného přístupu, jaký je uveden v následujících kódech, kde se používá vlastní direktiva BidiMediaDirective, která umožňuje podmíněně vkládat nebo odstraňovat elementy na základě směru textu aplikace:

typescript
import { Directive, EmbeddedViewRef, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
import { Subject } from 'rxjs'; import { distinctUntilChanged, filter, map, takeUntil, withLatestFrom } from 'rxjs/operators'; import { LocaleStateService } from '../../locale/data-access/locale-state.service'; const directionQueryPattern = /^\(dir: (?ltr|rtl)\)$/; @Directive({ exportAs: 'bidiMedia', selector: '[media]', }) export class BidiMediaDirective implements OnDestroy, OnInit {
#appDirection$ = this.localeState.locale$.pipe(
map((locale) => getLocaleDirection(locale)) ); #destroy = new Subject(); #queryDirection = new Subject(); #queryDirection$ = this.#queryDirection.pipe(distinctUntilChanged()); #validState$ = this.#queryDirection$.pipe( withLatestFrom(this.#appDirection$), map(([queryDirection, appDirection]) => ({ appDirection, queryDirection, })), filter(({ appDirection, queryDirection }) => appDirection !== undefined && queryDirection !== undefined) ); #view?: EmbeddedViewRef;
@Input() set media(query: string) {
if (!this.isDirection(query)) { throw new Error(`Invalid direction media query "${query}". Use format "(dir: ltr|rtl)"`); }
this.#queryDirection.next(this.queryToDirection(query));
}
constructor( private template: TemplateRef, private container: ViewContainerRef, private localeState: LocaleStateService ) {} ngOnInit(): void { this.attachElementOnDirectionMatch(); this.removeElementOnDirectionMismatch(); } ngOnDestroy(): void { this.#destroy.next(); this.#destroy.complete(); } private attachElement(): void { if (this.#view) { return; } this.#view = this.container.createEmbeddedView(this.template); } private attachElementOnDirectionMatch(): void { const directionMatch$ = this.#validState$.pipe( filter(({ appDirection, queryDirection }) => queryDirection === appDirection) ); directionMatch$.pipe(takeUntil(this.#destroy)).subscribe(() => this.attachElement()); } private isDirection(query: string): boolean { return directionQueryPattern.test(query); }
private queryToDirection(query: string): Direction {
return query.includes('ltr') ? 'ltr' : 'rtl'; } }

Tato direktiva implementuje způsob, jak reagovat na změny směru textu aplikace, a podmíněně vkládá nebo odstraňuje elementy na základě směru, který je aktuálně aplikován.

Tento přístup ukazuje, jak flexibilně a dynamicky můžeme optimalizovat aplikaci pro různé regiony a jazyky, což může výrazně zlepšit uživatelský zážitek, zejména pro aplikace, které mají globální publikum.

Důležité je si uvědomit, že takový přístup není omezen pouze na směr textu, ale může být rozšířen i na jiné aspekty lokalizace, jako jsou formáty dat, měny nebo specifické regionální požadavky na uživatelské rozhraní. Tato flexibilita je klíčová pro tvorbu aplikací, které se snadno přizpůsobí různým kulturním a jazykovým potřebám, čímž se zvýší jejich přitažlivost a použitelnost na mezinárodní úrovni.