L'objectif est de réaliser un chat mono-fenêtre en angular et sans code serveur. L'application est déployée sur vercel à chaque commit : https://accul-tahc.vercel.app
L'instalation de compodoc permet de générer une documentation à partir du code.
npm run compodoc:build-and-serve
Une petite batterie de tests unitaires sont mis en place avec karma.
npm run test
Eslint un linter, il marche de paire avec Prettier. Eslint dicte les règles et Prettier formate le code.
Mise en place de la commande Hot Module Replacement pour le développement local.
J'ai pris le choix de segmenter : les features d'un côté et les composants réutilisables/models/constantes de l'autres.
L'idée est de prévoir une refacto simple et rapide si on doit faire grandir le projet.
Dans une optique de performance, j'ai appliqué un lazy loading à deux niveaux :
-
de type composant standalone : le home component utilise le lazy loading de composant d'Angular 14 et donne accès à la feature chat
-
de type module : la feature chat est lazy loadée.
On chargera cette feature uniquement en navigant sur la route la concernant.
Le choix d'un sharedModule permet de pouvoir avoir un ensemble de composants (ainsi que de pipes et directives même si ici, cela nous concerne pas), partageable et incluable dans l'ensemble des features/modules demandés.
Les composants sont de type smart/dumb : leur perimètre fonctionnel est petit et très précis, l'intelligence est délégué au composant de feature qui les intègre et ochestre le tout.
Le choix d'un service d'état pour gérer les messages permet d'exploiter deux concepts utiles dans notre application :
-
le singleton : le service d'état n'existe qu'en une seule instance et est injecté à partir du chatModule
providedIn: 'root'
indique qu'il sera injecté par l'injecteur root de notre application.Notre ChatModule étant lazy loadé et notre service uniquement utilisé dans celui-ci, il sera alors injecté et inclus dans le bundle de ChatModule
-
le behaviorSubject : c'est un subject.
Un subject est à la fois observateur et observable.
Un behaviorSubject aura en plus un état initial.
Quand on s'y abonne, on recoit la dernière valeur qui passée dans le flux.
Grâce à lui, nous pouvons gérer l'état des messages de chat.
Le behaviorSubject est quand même limité, les données ne sont pas persistées. Interagir avec le localstorage permet de pouvoir retrouver la liste des messages précédement échanger en les enregistrant dans celui-ci.
Les barrels permettent un regroupement et une exposition des éléments sur des points uniques.
J'ai ajouté la possibilité à l'application d'être instalable par l'intermédiaire du navigateur (chrome et edge en desktop / chrome/safari/firefox en mobile). L'application peut également fonctionner en hors ligne quand elle a été lancé au moins une fois (ou installée)
L'application peut-être amener à s'internationaliser. Si c'est le cas, il faudra utiliser un système de fichier de langue comme i18n. https://angular.io/guide/i18n-overview
Le service d'état devra se brancher à un service de facade qui ira communiquer avec le back pour la gestion des messages.
Le localstorage n'aura plus d'utilité en l'état.
Les fonctionnalités sont présentes dans le service d'état mais non implémententées dans l'UI.
Lors d'instructions très proche dans le temps, on souhaite pouvoir attendre que le DOM est fini de réagir.
Une solution pour pouvoir faire passer une fonction au cycle de détection suivant est l'utilisation d'un setTimeout.
ScrollBottom vient regarder si nous sommes en fin de scroll après avoir reçu une nouvelle références de la liste des messages et donc fait muter le DOM.
J'ai découvert l'existence du mutationObserver, pour pouvoir réagir en fonction de l'ajout de noeud HTML. Cette une solution a creuser (je ne connais pas l'impact en performance de ce type d'observer)
https://developer.mozilla.org/fr/docs/Web/API/MutationObserver