L'intégration de Google Maps dans une application Angular peut sembler complexe au premier abord, mais l'outil fournit une série de composants et de directives permettant de manipuler la carte de manière simple et efficace. Dans cette section, nous explorerons les composants les plus courants du package @angular/google-maps, notamment le composant principal GoogleMap, ainsi que les composants MapInfoWindow, MapMarker et MapMarkerClusterer.

Le premier pas pour intégrer Google Maps dans une application Angular consiste à charger l'API JavaScript de Google Maps. Cela nécessite une clé API, qui doit être intégrée dans l'application afin d'accéder aux services de Google Maps. Un exemple classique consiste à rendre conditionnelle l'affichage du composant GoogleMap après le chargement de l'API. Le code suivant montre comment utiliser un Observable pour surveiller si l'API est prête avant de rendre le composant :

typescript
import { Component, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { GoogleMap } from '@angular/google-maps';
import { Observable, of } from 'rxjs'; import { catchError, mapTo } from 'rxjs/operators';
import { AppConfig } from '../app-config';
@Component({ selector: 'app-map', templateUrl: './map.component.html', }) export class MapComponent { @ViewChild(GoogleMap, { static: false }) map?: GoogleMap; isGoogleMapsApiLoaded$: Observable<boolean> = this.http.jsonp( `https://maps.googleapis.com/maps/api/js?key=${this.config.googleMapsApiKey}`, 'callback' ).pipe( mapTo(true),
catchError(() => of(false)),
);
constructor(private config: AppConfig, private http: HttpClient) {} }

Ici, un Observable isGoogleMapsApiLoaded$ est créé pour surveiller le chargement de l'API Google Maps. Tant que l'API n'est pas prête, un composant de chargement (spinner) est affiché. Une fois l'API chargée, le composant GoogleMap peut être rendu dans le modèle Angular.

Le composant GoogleMap

Le composant GoogleMap constitue le point d'entrée principal pour l'intégration de Google Maps dans Angular. Ce composant sert de conteneur pour les autres composants de la carte. Il est une enveloppe spécifique à Angular du google.maps.Map de l'API JavaScript de Google. Ce composant accepte plusieurs propriétés d'entrée comme la position centrale de la carte, son type, ses dimensions et son niveau de zoom. Il est également possible de lui transmettre des options supplémentaires via l'objet google.maps.MapOptions.

En plus de ses propriétés d'entrée, le composant GoogleMap dispose de 19 événements de sortie, qui correspondent aux événements DOM décrits dans la documentation de l'API JavaScript de Google Maps pour le composant Map. Ces événements permettent de réagir à des actions telles que le zoom, le glissement de la carte ou la modification de la position du centre.

Le composant MapMarker

Le composant MapMarker permet d'ajouter des marqueurs personnalisés sur la carte. Il s'agit d'une enveloppe spécifique à Angular du google.maps.Marker. Ce composant accepte des propriétés d'entrée comme position, title, label et icon. Vous pouvez ainsi personnaliser le marqueur avec un texte ou une icône spécifique, par exemple, un drapeau de plage pour un point d'intérêt particulier.

typescript
const marker = new google.maps.Marker({
position: { lat: -34.397, lng: 150.644 }, title: 'Point d\'intérêt', icon: 'assets/images/beach_flag.png' });

Le composant MapMarker permet également de rendre ces marqueurs interactifs, en les rendant cliquables et en associant des événements à ces interactions, comme l'affichage d'une infobulle lorsque l'utilisateur clique dessus.

Le composant MapMarkerClusterer

Le composant MapMarkerClusterer permet de regrouper plusieurs marqueurs en un seul cluster lorsqu'on effectue un zoom arrière sur la carte. Cela est particulièrement utile lorsque vous travaillez avec un grand nombre de points d'intérêt, permettant ainsi de ne pas surcharger la carte. Ce composant est un wrapper spécifique à Angular autour du MarkerClusterer du package @googlemaps/markerclustererplus.

Pour utiliser ce composant, il est nécessaire d'importer un script externe via une balise <script> dans le modèle de votre application. Le MapMarkerClusterer possède plusieurs propriétés d'entrée, telles que minimumClusterSize, maxZoom, et zoomOnClick. Il existe également des événements de sortie qui signalent quand un cluster commence ou cesse de se former.

Le composant MapInfoWindow

Le composant MapInfoWindow permet d'afficher des fenêtres d'informations personnalisées sur la carte. Ces fenêtres sont souvent utilisées pour fournir des informations supplémentaires sur un marqueur lorsqu'on clique dessus. C'est une enveloppe Angular autour de la classe google.maps.InfoWindow de l'API JavaScript de Google Maps.

Le composant MapInfoWindow accepte des propriétés d'entrée telles que position, qui détermine où la fenêtre d'information sera affichée, ainsi que des options supplémentaires via google.maps.InfoWindowOptions. Vous pouvez aussi y insérer un contenu personnalisé, qui sera affiché lorsque la fenêtre est ouverte.

Les fenêtres d'informations peuvent être ouvertes et fermées programmétiquement via les méthodes open et close, et il est possible d'attacher une fenêtre à un marqueur particulier.

Précautions et bonnes pratiques

Il est important de noter que l'intégration de Google Maps dans une application Angular requiert une gestion attentive des performances. En particulier, les composants comme MapMarkerClusterer peuvent avoir un impact sur la performance si le nombre de marqueurs est trop élevé. Il est donc recommandé de toujours tester les performances de votre application, en particulier lorsque vous travaillez avec de grands ensembles de données géographiques.

En outre, assurez-vous de bien gérer les erreurs de chargement de l'API Google Maps. L'API peut parfois échouer à se charger en raison de limitations de réseau, d'une clé API invalide ou d'autres facteurs. La gestion des erreurs doit être correctement mise en place pour offrir une expérience utilisateur fluide.

Enfin, il est essentiel de prendre en compte la gestion des autorisations pour l'utilisation des services Google Maps dans votre application. En fonction des fonctionnalités que vous implémentez (par exemple, l'affichage des trajets en temps réel ou des informations de circulation), des données sensibles peuvent être utilisées. Assurez-vous d'informer vos utilisateurs sur la manière dont leurs données sont traitées, conformément aux normes de confidentialité en vigueur, notamment le RGPD pour les utilisateurs européens.

Comment optimiser l'utilisation du compilateur Angular Compatibility Compiler (ngcc) et de l'Angular Linker pour des applications Angular compatibles Ivy

L'Angular Linker est un composant essentiel du framework Angular qui remplace progressivement l'Angular Compatibility Compiler (ngcc). Ce changement vise à offrir une meilleure compatibilité avec Ivy, le moteur de rendu d'Angular. L'Angular Linker intervient spécifiquement pour convertir une bibliothèque Angular partiellement compilée avec Ivy en une version entièrement compatible Ivy avant d'être incluse dans la compilation de l'application. L'Angular Compatibility Compiler, quant à lui, sera progressivement supprimé dans les versions futures d'Angular, à partir d'une version postérieure à la 12.2, et ne pourra plus être utilisé pour les bibliothèques compilées partiellement avec Ivy.

Dans cette dynamique, comprendre le rôle de ces deux outils et leur application dans le processus de développement d'une application Angular devient primordial pour optimiser la performance et la compatibilité des applications avec Ivy. Le processus de transition, bien que nécessaire, doit être maîtrisé pour éviter toute régression dans la qualité de l'application ou la vitesse de compilation.

Lorsque nous parlons de l'Angular Compatibility Compiler, il convient de noter qu'il était nécessaire, dans certaines versions d'Angular 9, de l'exécuter manuellement avant de démarrer le serveur de développement, d'exécuter les tests automatisés ou de construire l'application. Les versions ultérieures ont simplifié ce processus en intégrant une gestion automatique de ce compilateur via l'Angular CLI, bien qu'il soit toujours possible de l'exécuter manuellement pour optimiser la vitesse de compilation.

Utilisation du Compilateur Angular Compatibility Compiler

Le compilateur Angular Compatibility Compiler (ngcc) doit être exécuté avant certaines actions essentielles comme :

  • Démarrer un serveur de développement.

  • Exécuter des tests automatisés.

  • Construire l'application.

Chaque fois qu'une nouvelle version d'une bibliothèque Angular ou une nouvelle bibliothèque Angular est installée à partir d'un registre de paquets, il est impératif d'exécuter à nouveau le ngcc. Pour alléger ce processus, il est recommandé d'exécuter le ngcc en tant que tâche post-installation dans le gestionnaire de dépendances. Cela permet de ne pas devoir attendre la prochaine étape de construction ou de test. Pendant ce temps, le code source peut être modifié, ce qui permet une grande flexibilité.

Dans le cadre de l'utilisation du ngcc, plusieurs options peuvent être configurées, notamment :

  • --create-ivy-entry-points : Crée un sous-répertoire __ivy_ngcc_ dans chaque bibliothèque Angular, où seront stockées les versions compilées avec Ivy. Cette option empêche d'écraser les fichiers de bibliothèque originaux.

  • --first-only : Utilisé avec l'option --properties, cette option compile uniquement le premier format de module reconnu dans un paquet.

  • --properties : Cette option permet de spécifier les formats acceptables des paquets de bibliothèque à compiler, en indiquant les propriétés dans le fichier package.json du paquet.

  • --target : Compile spécifiquement un paquet, ce qui permet de cibler un module précis comme @angular/material/button.

  • --tsconfig : Permet de cibler un projet spécifique dans un espace de travail Angular.

  • --use-program-dependencies : Compile uniquement les paquets de bibliothèque importés dans l'espace de travail ou le projet Angular.

L'exécution manuelle de ngcc permet de contrôler la vitesse de compilation, notamment dans des cas où des bibliothèques sont modifiées ou ajoutées fréquemment. En pratique, une commande standard comme ngcc --first-only --properties es2015 module fesm2015 esm2015 browser main --create-ivy-entry-points peut être utilisée pour optimiser les performances de compilation. Ce processus garantit une compilation plus rapide et évite la réécriture inutile des fichiers de bibliothèque.

Optimisation du processus CI/CD avec Angular Compatibility Compiler

Dans un environnement de CI/CD, il peut être coûteux en termes de performance de restaurer toute la bibliothèque node_modules lors de chaque exécution. Il est donc recommandé de privilégier le cache des gestionnaires de paquets au lieu de conserver l'intégralité du dossier node_modules. Cependant, cela implique que le compilateur Angular Compatibility devra être exécuté à chaque étape du workflow CI/CD, car il travaille à partir de zéro à chaque fois.

L’optimisation du processus dans un tel environnement passe par l’utilisation de la commande suivante dans un hook post-installation :

css
ngcc --first-only --properties es2015 module fesm2015 esm2015 browser main --create-ivy-entry-points

Cette approche permet de ne compiler qu'un format de paquet à la fois et de privilégier les formats les plus rapides à compiler. Dans le cadre d'une compilation CI/CD, il est également pertinent d'envisager des stratégies de cache ou des optimisations spécifiques en fonction des versions d'Angular utilisées. Par exemple, dans les versions 9.0 et 11.1, il peut être plus efficace de laisser de côté l'option --create-ivy-entry-points, au profit de la compilation en place des paquets.

L’utilisation du ngcc dans un workflow automatisé permet non seulement de gagner du temps en ajustant le processus de compilation, mais également de mieux gérer les dépendances entre les bibliothèques et d'améliorer la vitesse de développement.

Ce qu'il faut retenir

Il est crucial de comprendre que l’Angular Compatibility Compiler et l'Angular Linker sont des outils complémentaires, mais distincts, dans le processus de migration vers Ivy. Le rôle de ngcc est de transformer les bibliothèques pré-compiled en format Ivy, tandis que l'Angular Linker s'occupe de s'assurer que tout est correctement relié au moment de la compilation finale.

La maîtrise de ces outils est indispensable pour optimiser les performances de compilation, surtout dans des environnements complexes ou des projets de grande envergure. Cela inclut non seulement la compréhension de leurs fonctionnalités, mais aussi leur utilisation dans des contextes variés, comme dans les workflows CI/CD ou lors de l'ajout de nouvelles dépendances.

La clé du succès réside dans une utilisation flexible et stratégique de ces outils, avec un ajustement constant des options en fonction des spécificités de chaque projet.

Optimisation du temps de compilation dans les workflows CI/CD d'Angular

Dans un environnement de développement moderne, l'efficacité des processus d'intégration continue et de déploiement continu (CI/CD) joue un rôle primordial dans la gestion des applications Angular. L'un des éléments clés pour améliorer la vitesse des builds et des tests dans ces workflows est l'optimisation de la compilation, en particulier lorsqu'il s'agit de traiter les applications Angular au sein d'un monorepo.

Lorsqu'un projet Angular utilise des bibliothèques populaires comme Angular Material ou Angular CDK, qui comportent de nombreux sous-paquets, il est souvent inutile de compiler l'intégralité de ces bibliothèques pour chaque application. En effet, dans un monorepo, certaines applications peuvent dépendre de seulement une partie des sous-paquets d'une bibliothèque. Cela devient particulièrement pertinent dans les jobs CI/CD ciblant une application spécifique, par exemple lors d'un test ou d'une compilation dédiée.

Pour mieux comprendre cette optimisation, prenons un exemple concret. Imaginons un monorepo contenant deux applications Angular distinctes : l'une utilise la bibliothèque Bootstrap pour ses composants UI, et l'autre utilise Angular Material. Si nous effectuons un test ou une compilation pour l'application utilisant Bootstrap, il est inutile de compiler toutes les dépendances d'Angular Material. La commande suivante peut être utilisée pour cibler uniquement les paquets nécessaires et gagner ainsi un temps précieux dans le processus de CI/CD :

css
npx ngcc --first-only --properties es2015 module fesm2015 esm2015 browser main --create-ivy-entry-points --tsconfig projects/bootstrap-app/tsconfig.app.json --use-program-dependencies

Dans cet exemple, l'option --tsconfig spécifie le fichier de configuration TypeScript de l'application ciblée (ici l'application Bootstrap), tandis que l'option --use-program-dependencies garantit que seules les dépendances nécessaires à cette application seront compilées. Cela permet d'éviter une surcharge inutile de compilation pour des bibliothèques non utilisées par cette application.

Cette approche peut également être appliquée dans le cas où une application utilise Angular Material, mais uniquement certains de ses sous-paquets. Voici une commande similaire pour optimiser le temps de compilation :

css
npx ngcc --first-only --properties es2015 module fesm2015 esm2015 browser main --create-ivy-entry-points --tsconfig projects/material-app/tsconfig.app.json --use-program-dependencies

Dans ce cas, la différence réside dans le fait que le chemin du fichier tsconfig est modifié pour cibler l'application qui utilise Angular Material. Encore une fois, cette méthode permet de ne compiler que les sous-paquets d'Angular Material effectivement utilisés par l'application.

En intégrant ces stratégies dans les processus CI/CD, on peut significativement réduire le temps de compilation, rendant ainsi les workflows beaucoup plus rapides et réactifs. Cependant, il est essentiel de comprendre que cette optimisation ne concerne que les cas où certaines bibliothèques comme Angular Material ou Angular CDK sont partiellement utilisées dans les applications d'un monorepo. Il ne s'agit pas d'une solution universelle, mais d'une méthode ciblée qui s'applique principalement à des scénarios spécifiques de gestion des dépendances dans des projets Angular complexes.

Enfin, il est important de noter que l'optimisation de la compilation dans un environnement CI/CD ne se limite pas à l'utilisation de la commande ngcc ou de l'option --use-program-dependencies. D'autres techniques, telles que l'utilisation de caches dans les systèmes CI/CD, l'optimisation de la gestion des dépendances au sein des projets ou encore la configuration précise des paramètres de compilation, jouent également un rôle crucial pour atteindre une efficacité maximale. Ces pratiques permettent non seulement de réduire le temps nécessaire à la compilation, mais aussi de garantir que les processus de développement restent fluides et que les erreurs potentielles sont minimisées.

Comment migrer votre application Angular de View Engine à Ivy : un guide essentiel pour la transition

Lors de la migration de votre application Angular de View Engine vers Ivy, plusieurs ajustements sont nécessaires pour garantir une transition en douceur et optimiser le comportement de votre application avec les nouvelles versions d'Angular. Un des changements majeurs concerne l'option static dans les requêtes de vue et de contenu. Dans Angular View Engine, ces options étaient facultatives, mais avec la version 8, Angular impose la définition explicite de l'option static. Par exemple, les propriétés de requête de vue doivent désormais être définies comme suit : @ViewChild('error', { static: false }) et @ViewChild('greeting', { static: true }).

L'introduction de cette contrainte avec Angular 8 est en réalité un ajustement pour améliorer la prévisibilité du comportement des requêtes, en particulier celles qui concernent des éléments imbriqués dans des vues structurées créées par des directives structurelles. Cette migration vers Angular Ivy en version 9 rend l'option static optionnelle, mais elle est par défaut définie sur false. Ainsi, les propriétés de requêtes de vue deviennent comme suit : @ViewChild('error') et @ViewChild('greeting', { static: true }). Il est important de souligner que les listes de requêtes ne sont pas affectées par ces changements historiques, car elles sont toujours considérées comme dynamiques.

Avant de migrer votre application, il est crucial de revoir vos requêtes de vue et de contenu. Le guide de migration pour les requêtes statiques et dynamiques est toujours disponible dans la documentation Angular, et sa consultation vous permettra de mieux comprendre les implications de ces modifications sur votre code.

Une autre migration notable est celle liée au changement du wrapper async vers waitForAsync. Cette migration renomme la fonction de rappel async utilisée pour les tests afin de dissiper toute confusion avec la syntaxe async-await. waitForAsync attend que toutes les micro-tâches et les macro-tâches soient terminées avant de finaliser le cas de test. Ce changement s'inspire des fonctions done utilisées dans des bibliothèques comme Jasmine et Jest.

La migration vers Angular Ivy version 9 introduit aussi un ajustement dans la gestion des décorateurs @Injectable. Si une classe est enregistrée en tant que fournisseur basé sur une classe, Angular Ivy s'assure que le décorateur @Injectable est appliqué, même si l'annotation était absente auparavant. De plus, les fournisseurs incomplets dans Angular View Engine sont maintenant transformés en fournisseurs de valeur pour la valeur indéfinie.

Ce processus de migration s'étend également à la gestion des configurations par défaut dans Angular CLI. À partir de la version 12 d'Angular, le mode de production devient la configuration par défaut lors de la génération des builds de projet. Cela permet de simplifier les commandes de construction en évitant la nécessité de spécifier --configuration=production. Cependant, il est important de noter que les projets existants ne sont pas automatiquement migrés vers cette configuration par défaut, et une migration manuelle est recommandée pour en bénéficier.

En ce qui concerne les migrations manuelles, il est essentiel d'optimiser la détection des changements et de configurer le NgZone. Par exemple, lorsque vous initialisez votre application avec PlatformRef#bootstrapModule, vous pouvez désormais spécifier des options comme ngZoneEventCoalescing et ngZoneRunCoalescing. Ces options optimisent la détection des changements en regroupant plusieurs demandes de détection dans une seule opération, ce qui peut améliorer les performances de l'application, surtout lorsque plusieurs événements DOM sont déclenchés simultanément.

Les migrations manuelles, bien que facultatives, sont cruciales pour garantir que votre application utilise les meilleures pratiques et tire pleinement parti des fonctionnalités d'Angular Ivy. En ajustant correctement la gestion de la navigation initiale et en choisissant les bonnes options de zone (ngZone), vous pourrez maintenir une expérience utilisateur fluide et réactive.

Il est également important de souligner que la migration d'un projet existant peut parfois révéler des configurations ou des dépendances obsolètes. Il est donc conseillé de vérifier régulièrement la documentation officielle d'Angular et d’adapter les pratiques de développement aux nouvelles recommandations et mises à jour. Assurez-vous de tester rigoureusement chaque modification pour éviter les régressions et optimiser la stabilité de votre application.