Angular est un framework de réalisation d'interfaces graphiques HTML5/JavaScript utilisables dans un navigateur web.
Cette page a pour objectif d'introduire à l'utilisation d'Angular. Pour des informations plus exhaustives, on pourra se référer :
- à la documentation officielle Angular
- à la documentation de l'API du framework
- au code-source d'Angular
Editeur pour Angular
Il est tout d'abord requis de disposer d'un navigateur web pour tester ses créations ainsi qu'un éditeur de texte afin de développer son application. Parmi les éditeurs, outre les vénérables Vi(m) et Emacs, mais aussi des environnements de développement spécialisés parmi lesquels :
- Visual Studio Code (Microsoft). Cet éditeur Open Source multi-plateformes est développé en utilisant le framework Electron qui permet de réaliser des clients lourds en utilisant des technologies web avec le moteur de rendu HTML/JavaScript Chromium (à la base du navigateur Google Chrome). Le principal intérêt de VS Code est son support avancé du langage TypeScript utilisé pour le développement d'applications Angular.
- Atom (GitHub) est un autre éditeur Open Source basé sur le framework Electron développé en CoffeeScript (un langage étendant JavaScript). Il offre une bonne intégration avec GitHub, beaucoup de plugins d'extension ainsi que des fonctionnalités de personnalisation assez complètes. Son principal point faible réside dans une consommation de ressources importantes et une certaine lenteur.
- WebStorm (JetBrains). Cet IDE est un logiciel commercial payant basé sur l'éditeur IntelliJ (également utilisé pour Android Studio ou PyCharm). WebStorm supporte les frameworks de développement web Angular mais aussi React (code JSX) et VueJS. Une version freeware existe pour les utilisateurs académiques (enseignants et étudiants).
L'intérêt de l'utilisation d'un environnement de développement intégré (IDE) réside dans les fonctionnalités d'autocompletion, d'exploration de code, de génération de code idiomatique ainsi que de consultation de la documentation. Un éditeur de texte classique se contente généralement d'assurer des fonctions de coloration syntaxique pour les langages supportés.
Installation d'Angular
L'utilisation d'Angular requiert le gestionnaire de paquetages npm de Node.js. Il est possible de le télécharger depuis la page d'accueil du projet Node.js. Si vous utilisez une distribution Linux, il est possible que des paquetages adaptés soient déjà préconstruits pour celle-ci.
Nous installons ensuite globalement la Commande-Line Interface d'Angular avec cette commande :
npm install -g @angular/cli
Nous pouvons ensuite vérifier qu'Angular est bien installé en demandant l'aide de la CLI pour afficher toutes les commandes supportées :
ng help
Remarque : si NodeJS et npm sont installés globalement, on peut installer Angular dans son répertoire utilisateur (sans être administrateur) en suivant les conseils de cette page.
Création d'un nouveau projet avec le CLI
Un nouveau projet Angular se créé avec la commande :
ng new nameOfTheProject
La CLI peut nous poser des questions sur la configuration du projet. Souhaitons-nous activer le module de routage ? Il est possible aussi de sélectionner une feuille de style CSS à utiliser par défaut (modifiable par la suite).
Observons le répertoire généré qui contient différents fichiers et répertoires :
- src/ est le répertoire le plus important car il contient toutes les sources du projet (déjà peuplé avec certains fichiers dont un composant app principal)
- package.json est le fichier de configuration d'un projet node ; il contient toutes les bibliothèques (dépendances) dont notre projet a besoin. Il est possible de rajouter de nouvelles dépendances en éditant ce fichier à la main ou en utilisant la commande npm install nameOfTheLibrary (cette commande modifie package.json et télécharge la bibliothèque en question ainsi que toutes ses dépendances transitives). On constate que par défaut angular a placé ses propres dépendances dans ce fichier ainsi que notamment core-js et rxjs. Il est possible aussi de définir des raccourcis vers des commandes dans ce fichier.
- tsconfig.json est le fichier de configuration du transpilateur TypeScript. Normalement les options par défaut devraient convenir.
- tslint.json configure le comportement de l'outil lint de TypeScript qui permet de vérifier si le code suit un formatage correct (indentation correcte, nommage cohérent des symboles...) et émettre d'éventuels avertissements. Il est possible de linter l'application avec la commande ng lint
- e2e/ contient les sources des tests End To End : il s'agit de tests d'intégration destinés à vérifier le fonctionnement global de notre application (ce ne sont donc pas des tests unitaires). Ces tests reposent sur les bibliothèques protractor et jasmine qui permettent de définir des scénarios de tests sur l'interface graphique (clics sur tel ou tel éléments) et les résultats attendus (affiche de tel texte dans une zone...).
- node_modules/ : ce répertoire très volumineux contient les sources de toutes les bibliothèques dont dépend notre projet. Ce répertoire peut aisément contenir ~30 000 fichiers représentant au total plusieurs centaines de Mo même pour une simple application hello world. Ce répertoire n'a pas à être partagé si le projet est publié ; il peut être effacé sans risque car regénérable à tout moment par npm (à condition d'avoir une bonne connexion Internet pour retélécharger toutes les bibliothèques)
Création d'un composant
La brique fondamentale d'une application Angular est le composant. Il s'agit d'un composant graphique élémentaire potentiellement réutilisable dans différents contextes qui nous sert à afficher et interagir avec des données. Un bon découpage en composants nous permet de réaliser une application modulaire.
Par défaut, tout projet Angular nouveau contient un composant app présent dans le répertoire src/app. Il s'agit du composant principal d'accueil qui sera affiché à l'ouverture de notre application. Ce composant hébergera d'autres composants que nous réaliserons ensuite.
Chaque composant est présent dans son propre répertoire. Il est typiquement constitué des fichiers suivants :
- name.component.ts : ce fichier contient le code TypeScript du composant afin d'indiquer sa mécanique de fonctionnement. C'est ici que nous spécifions le code à exécuter lorsque le composant est créé, lorsqu'il est détruit, les attributs du composant, que faire lorsque l'on clique ou modifie un élément du composant...
- name.component.html : ce fichier contient le template HTML du composant. Il s'agit du code HTML affiché par le composant. Le template n'est pas que du pur code HTML, il y a aussi des instructions de template pour injecter des données (avec éventuellement une liaison lecture-écriture avec le composant), afficher conditionnellement du code, faire une boucle d'affichage...
- name.component.css : il s'agit de la feuille de style CSS utilisée pour le rendu des styles pour les éléments HTML du composant. Il existe aussi une feuille de styles globales src/styles.css partagée par tous les composants.
- name.component.spec.ts : il s'agit d'un fichier décrivant des tests unitaires à appliquer sur le composant pour vérifier son comportement.
- name.module.ts : c'est dans ce fichier que nous décrivons tous les composants utilisés par notre composant (composants dont il est dépendant) ainsi que les composants exportés. Ce fichier est utilisé par le composant racine app : tous les composants utilisés par l'application y sont déclarés.
Pour créer un nouveau composant nous pouvons copier le répertoire d'un composant existant qui nous servira de base ou alors demander la création d'un composant vierge avec la commande (à la racine du projet) :
ng generate component helloWorld
Le répertoire est généré (normalement dans le répertoire src/app/my-component comme sous-composant de app) et nous pouvons observer le composant vide :
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-hello-world', templateUrl: './hello-world.component.html', styleUrls: ['./hello-world.component.css'] }) export class HelloWorldComponent implements OnInit { constructor() { } ngOnInit() { } }
L'annotation @Component indique les propriétés essentielles du composant :
- selector spécifie le nom du composant que l'on utilisera comme balise dans le code HTML des templates pour l'évoquer
- templateUrl indique le chemin vers le template (code HTML de la vue) du composant. Notons qu'il est possible aussi d'embarquer directement le template dans l'annotation @Component (à réserver pour les petits templates). Dans ce cas, on utilise template: 'contenu du template à embarquer'
- styleUrls indique des chemins vers des feuilles de style CSS à appliquer
Un composant comporte un constructeur comme toute classe TypeScript qui se respecte. Celui-ci peut avoir des paramètres qui seront utilisés par le composant : si ces paramètres sont préfixés par un mot-clé de visibilité (private ou public), ils sont considérés comme des champs de la classe (l'initialisation avec this.fieldName = fieldName devient donc inutile).
Pour débuter, nous pouvons réaliser un composant affichant un message de bienvenue personnalisé avec un nom en paramètre. Le template étant assez concis, nous l'intégrons dans l'entrée template de l'annotation @Component :
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-hello-world', template: '<p>Hello World for {{ userName }}</p>', styleUrls: ['./hello-world.component.css'] }) export class HelloWorldComponent implements OnInit { @Input() userName: string; // tous les champs utilisés avec les templates Angular doivent être publics (c'est le cas par défaut) ! constructor() { } ngOnInit() { } }
Nous intégrons ensuite ce composant dans le template app.component.html du composant principal app :
<div> Here is our Hello World component: <app-hello-world userName="fooBar"></app-hello-world> </div>
Il est possible aussi de modifier directement le fichier src/index.html qui est le fichier HTML racine de notre application (qui par défaut affiche le composant principal app).
Nous pouvons ensuite compiler les sources et lancer le serveur de test d'Angular avec la commande suivante :
ng serve
Par défaut, le serveur HTTP de test est démarré sur le port 4200 de la boucle locale. On peut donc y accéder depuis l'adresse http://localhost:4200. Lorsque des fichiers sont modifiés alors que le serveur de test est actif, une retranspilation des sources est automatiquement réalisée.
Déploiement de l'application
Le serveur de test n'a pas vocation à être utilisé en production. Pour publier notre application (après s'être assuré qu'elle fonctionne correctement), nous demandons sa construction avec la commande ng build. Le compilateur détermine tous les objets et fonctions utiles pour le fonctionnement de notre application et les réunit dans des fichiers JavaScript écrits (ainsi que les styles dans un fichier css) dans le répertoire dist. Le contenu de ce répertoire pourra être rendu accessible par le serveur web de notre choix (Apache, Nginx, Lighttpd...).
Par défaut, ng build génère des fichiers js.map qui permet de faire le lien entre le code JavaScript transpilé et le code source original (ce qui facilite le débuggage). Avec ng build --prod, ces fichiers d'aide au débuggage ne sont pas générés.
Pour en savoir plus sur le déploiement, on pourra consulter cette page de la documentation Angular.
En cas de problèmes
- En cas d'erreur de syntaxe ou de typage, ng serve ou ng build signale le problème en console par un message d'erreur (généralement assez explicite)
- Même si la compilation réussit, des exceptions sont toujours possibles à l'exécution (notamment lorsque les templates sont compilés à la volée en mode JIT) : il faut utiliser la console JavaScript du navigateur pour les examiner. Une erreur courante étant par exemple d'utiliser un nom de composant non existant dans un template.
- Quelquefois ng serve ne détecte plus les modifications de fichier pour réaliser une recompilation automatique ; il faut alors arrêter et redémarrer le serveur
- Si le répertoire node_modules est corrompu (ou inexistant), il est possible de réinstaller toutes les dépendances utilisées avec la commande rm -rf package-lock.json node_modules && npm install