react dark light theme material Cours web frontend – React

Dark, Light & Custom thème avec React/Material Ui

Pour aujourd’hui je vous propose une petite implémentation d’un thème sous React avec la lib Material-Ui, l’implémentation de Material Design de Google.

Je vous met mon dépot Github pour avoir le code source complet du projet.

react material ui theme light dark

Objectifs

  • Thème dark & light dans toute l’app
  • Système de sauvegarde des préférences utilisateurs via local-storage

 

Pré-requis

Il va vouloir quelques dépendances NPM tel que:

  • React
  • Material-ui

 

Initialisation de CssBaseline

On ajouter le composant CssBaseline en entrée de notre application. Mais à quoi set t-il ?

Il va nous permettre de remplacer certaines props CSS de base de notre app, faire certains reset. Cela va permettre d’éviter certains props de mal switcher entre Dark et Light theme.

Nous avons donc dans notre fichier root :

  • ThemeHandler: on va décrire ce composant juste ensuite 😉
  • CssBaseline: notre composant pour le bon switch dark/light
  • ContentApp: notre composant qui va contenir le reste de notre app

Disons qu’il fait un semblant de normalize.css, mais pour Mui 🙂

 

Création de la palette de notre thème

On va définir dans ce composant tout les hyperparamètre qui touche à l’aspect visuel du thème, ainsi que sa palette de couleurs.

On va définir les props suivants:

  • local_storage_key: string/id de la props qui nous permet de savoir le thème courant de l’utilisateur. On va détailler le local storage plus tard dans l’article
  • baseTheme: thème parent qui va définir les paramètres globaux qui seront utilisé à la fois pour le dark que le light
  • dark_theme:  palette spécifique au thème dark
  • light_theme: palette spécifique au thème light

 

Création du contexte du thème

On va définir un contexte pour notre thème. Cela va nous permettre au sein de l’ensemble de notre application de récupérer des informations à propos du thème. Il va nous être important dans la suite de l’article. Pour le moment on initialise un contexte vide :

 

 

Création du gestionnaire de thème

On souhaite maintenant un système de gestion de thème. On souhaite qu’il garde l’état actuel du thème (palette dark ou light), mais aussi qu’il ait une fonction permettant de switch de thème.

 

Nous définissions en premier lieu un useState. Il va nous permettre de changer la valeur du thème en cours, mais aussi de la récupérer. On va l’initialiser avec le local storage de l’user. Il va nous permettre de garder la préférence de l’user dans le navigateur ( une sorte de cookie )

On init un objet de contexte avec :

  • isDark: boolean si le thème en cours est dark
  • toggleTheme: function permettant le switch de thème

La fonction toggleTheme permet de setter une nouvelle valeur du boolean, et permet de mettre à jour la valeur du local storage.

La fonction getTheme permet de retourner la bonne palette de couleurs en fonction du boolean courant.

D’un point de vue HTML, le composant ThemeHandler est composé de la sorte:

  • themeContext.Provider: permet de consommer une valeur par défault de context ( on la init auparavant)
  • themeProvider: permet de fournir un thème à notre application avec celui défini dans le context précédent
  • {props}: permet d’insérer les nodes enfants que l’on fournira au composant

 

Ajout de contenu pour notre app

Le système de switch et gestion de thème est mis en place. Il nous faut maintenant quelques composants UI avec un toggle, permettant de switch entre dark et light.

Grace au useContext, on va pouvoir récupérer le context du thème. Ceci va nous permettre de connaître le type de thème actuel au sein de notre application, ainsi que de la function pour switch de thème.

A partir de ce context, vous pouvez ajouter un bouton, un switch ou autre afin de le bind avec la function de switch de theme toggleTheme, et aussi d’initialiser votre composant avec l’état en cours via le isDark.

react native expo android ios sqlite Cours web Mobile – React Native

Chap 6 : Stockage de données complexes (SQLite)

Nous avons vu dans le chapitre précédent comment stocker en local des données simples.

On va s’attarder cette fois-ci à comment stocker des informations plus nombreuses, plus complexes et ce de façon plus ordonnée, en utilisant des bases de données SQL.

On va réaliser une simple to-do app, avec possibilité d’ajouter une note, ou d’en supprimer, avec une liste permettant de toute les afficher.

 

Code source du chapitre disponible sur Github.

 

On ne peut utiliser n’importe quel outils pour persister des données car nous sommes sur un projet Expo, nous empêchant d’accéder aux modules natifs de iOS et Android. SQLite est un moyen fonctionnant avec des projets Expo.

 

Objectifs

  • Stocker localement des informations via une base de donnée SQL

 

react native sqlite

 

Prérequis

Installez le package pour utiliser SQLite :

expo install expo-sqlite

 

Nous l’importerons dans nos fichiers de la manière suivante :

import * as SQLite from 'expo-sqlite';

Base de données & CRUD

CRUD : diminutif correspondant aux requêtes basique, à savoir Create, Read, Update et Delete.

Création de la base de données

Rien de plus simple, une seule ligne suffit :

On donne un nom à notre base, en argument. Celle-ci n’est crée qu’une seule et unique fois. Si on rappelle cette même méthode, on récupère la base de donnée crée auparavant, aucun risque de doublon.

 

Création de la table NOTE

On va maintenant créer notre table. Je vous montre la façon la plus simple de réaliser des transaction SQL vers notre base :

Requête SQL des plus basique avec le mot clé CREATE TABLE. On lui donne un nom de table, ainsi que la définitions de nos colonnes. Un ID auto-incrémenté pour garantir l’unicité de nos données, ainsi qu’un attribut TEXT qui contiendra le contenu de nos notes.

Nos deux attributs ne peuvent être null, et on leur défini un type, soit Text ou Integer.

 

Optimiser les requêtes

Je préfère une autre annotation que la précédente pour questionner la base de données, récupérer nos objets et leurs affecter des transformations. Je trouve plus clair et simple à l’utilisation. On définit notre modèle de requête avec une promesse :

On pourra utiliser ce modèle dans des fonctions async, via un appel par un await. On pourra utiliser des then() et catch() à l’appel du service dans nos vues, permettant par exemple d’afficher à l’utilisateur dans une popup si une note à bien été ajouté ou si dans le cas inverse afficher un message d’erreur avec son origine.

 

Récupérer toute les notes

On définit une interface pour les objets que l’on va récupérer en base. Cela nous facilitera leurs manipulations au sein de notre application :

 

On fait appel à notre modèle pour questionner la base :

On récupère nos objets via la requête. On va itérer sur notre résultat de requête pour re-typer correctement nos objets.

 

Ajouter une note

Seule différence, on va ici passer en argument le contenu de ma note que l’on souhaite persister en base. Pas besoin de lui passer un ID pour la note, car celle-ci est généré automatiquement en base. Nous avons défini cette option tout à l’heure, lors de la création de la table.

Supprimer une note

Quasiment identique au point précédent, sauf qu’ici on lui passe un ID de note à notre fonction, étant donné que c’est l’attribut qui défini l’unicité de mes items dans ma table NOTE :

 

Récupération des items dans la vue

Nous venons de créer notre base ainsi que des opérations CRUD permettant d’interagir avec elle. On va désormais créer une nouvelle vue, avec un champ de texte permettant de donner du contenu à une note, un bouton pour ajouter cette note, une liste scrollable permettant de naviguer sur l’ensemble de nos notes en base, et leur associé à chacun un bouton pour les supprimer.

 

Définition du state de notre vue

On commence par créer le squelette de base de notre vue :

On utilise ici un composant de classe et non un composant fonctionnel. On a besoin d’utiliser un state pour l’affichage dynamique du contenu de notre liste scrollable. On défini un attribut myNoteList correspondant à une liste de l’ensemble de nos notes en base, ainsi qu’un second attribut note correspondant au champ de texte remplissable par l’utilisateur pour créer une nouvelle note. On initialise les deux attributs dans le constructeur.

 

Définition des méthodes de notre vue

On défini les méthodes pour mettre à jour nos éléments, pour ajouter une note, ainsi que la supprimer :

La méthode componentDidMount() est une méthode standardisé de React, permettant d’être appelé une seule et unique fois et ce à la fin de la création du composant. On lui demande à l’ouverture de notre page, d’initialiser notre liste avec le contenu de notre base de données.

 

Définition des éléments visuels de notre vue

Ici rien de bien complexe. J’ai créer un titre de page, un champ de texte avec un bouton pour ajouter une note. Une liste scrollable présentant l’ensemble des notes en base, ainsi qu’une option permettant de les supprimer :

J’ai utilisé des icones Ionicons inclus dans Expo, qui s’adapte en fonction de si vous êtes sur Android ou iOS via la méthode Platform.OS, encapsulé dans des TouchableOpacity, pour rendre un peu plus esthétique mes boutons d’interactions, ainsi que des flexbox pour avoir une touche de responsive design.

 

Conclusion

Vous venez de voir comment créer très simplement une base de donnée pour votre application React Native tournant sous Expo, comment l’interroger et surtout comment récupérer et afficher le résultats dans une belle vue responsive.

android ios react native expo Cours web Mobile – React Native

Chap 1 : Environnement, prérequis & Hello world !

Résultat du cours

Objectif

  • Configurer l’environnement de développement
  • Générer le squelette basique d’une application
  • Tester son application sur son smartphone

 

Code source du chapitre disponible sur Github.
 

 

ReactNativeCLI, ExpoCLI…

Nous avons des outils dans le développment web, permettant de développer rapidement un squelette de base pour une application :

  • CLI pour Angular
  • CRA pour React
  • CLI pour React Native

 

Mais pour créer mon premier projet pour découvrir ces technos mobile, je pars non pas sur ReactNative CLI, mais sur ExpoCLI. C’est comme Rails mais pour ReactNative, ou encore Phonegap pour Cordova. Il étends les fonctionnalité de ReactNativeCLI.

Qu’apporte t-il de plus par rapport à React Native CLI et quand l’utiliser ?

Avantage :

  • Pas besoin d’Android Studio ni de Xcode
  • Configuration bien plus simple & rapide ( hello world en moins de une minute )
  • Hot reload, sur smartphone physique et non par simulateur. Oui, via l’appli Expo, vous pouvez tester votre app sur votre smartphone iOS ou Android physique, et ce instantanément. En react native vanilla, vous avez droit au simulateur Android sur Windows, et simulateur iOS sous macOS exclusivement.

Inconvénient :

  • Poids de l’apk/ipa, du à l’ajout de librairie annexes (~50mo le hello world, ça fait mal…)
  • Accès aux modules natifs impossible. Vous ne pouvez ajouter de lib natif via Xcode ou Android studio, car tout est packagé via le sdk Expo. Certaines fonctionnalité sont impossible d’être utilisé, comme les achats in-app ou le bluetooth.

 

En résumé, pour débuter le dév mobile ou pour de simples application, vous devriez commencer par Expo. Pour des utilisateurs expérimentés ou souhaitant des fonctionnalités spécifiques à chaque plateforme, partez sur du ReactNative vanilla.

 

Prérequis

Il vous faudra de base :

  • NodeJS

Installez ensuite la CLI de Expo via une console :

npm install -g expo-cli

Pensez à avoir Python dans vos variables d’environnements, au risque d’avoir une erreur d’installation.

 

Initialisation du squelette

On initialise une nouvelle application via la commande :

expo init "Nom_de_votre_app"

 

Vous aurez l’architecture suivante :

  • assets/ : dossier contenant vos images
  • app.json : fichier de configuration du projet
  • app.tsx : fichier d’entrée de votre application
  • package-json : contient l’ensemble des dépendances et scripts du projet
  • tsconfig.json : fichier de configuration de typescript
  • babel.config.js : fichier de configuration pour la gen du bundle ( une sorte de webpack )

 

Lancement du serveur de dév

Simple :

npm start

Un nouvel onglet dans votre navigateur va s’ouvrir, vous proposant divers options :

 

Pour faire fonctionner le simulateur Android ou iOS, vous allez devoir installer les biblio natives. Mais on peut éviter cela en utilisant notre propre smartphone. On va devoir connecter notre smartphone au même réseau wifi que l’ordinateur sur lequel on développe.

Installez l’application EXPO, disponible sur l’iOS Store et GooglePlay store, selon votre type de device. Une fois l’application lancé sur votre smartphone, vous allez pouvoir scanner le QR code affiché sur la console, comme montré sur la capture d’écran précédent. Cela va permettre de transférer le bundle directement sur le smartphone.

Vous allez pouvoir ainsi voir vos modification en temps réel sur votre téléphone, de l’application que vous codez, à chaque sauvegarde.

 

Icone & Splash screen

Vous pouvez changer l’icone de votre application via le fichier « app.json ».

De même pour le splash screen, qui correspond a l’image qui sera affiché le temps que votre application soit chargé par votre smartphone.

react native chap1 splash screen

 

Conclusion

Nous venons de voir comment réaliser un « HelloWorld » en quelques minutes, et ce directement sur notre smartphone.

On discutera dans le prochain chapitre sur comment générer les fichiers APK et IPA, permettant d’installer et de distribuer notre application.
 

electron jest spectron e2e unitaire test Cours logiciel - Electron

Chap 8 : Tests unitaires & end-2-end ( Spectron…

C’est lassant, ça prend du temps, et c’est bien souvent idiot au premier abord. Je vous présente donc….. les TESTS ! 😒 On les évites bien trop souvent, mais il faut le dire moi le premier, que l’on a tous connus des projets auquel à force de rajouts de fonctionnalités, que certaines unes d’entres elles, ont sans le vouloir casser d’autres fonctionnalités. En effet, quand on est sur une branche et que l’on focus cette nouvelle feature, on test celle-ci exclusivement dans l’environnement de développement. Et il se peut que l’on casse d’autres chose à vouloir bouger, modifier et optimiser notre code. Et on s’en rend bien souvent compte trop tard lors d’éventuelle realease en production, ce qui peut engendrer d’importantes conséquences. Ou dans le meilleur des cas comme moi, passer pour un con lors de mes démos 😅

 

Objectif

  • Installer & adapter les environnements Jest et Spectron à Electron
  • Réaliser des tests end-2-end
  • Réaliser des tests unitaires

 

Spectron & Jest : pourquoi et comment

Lors de la création d’un projet Angular via CLI, vous aurez d’avantage de chance de connaître les noms de Karma, Jasmine, ou encore Protractor, qui sont proposé par défaut.

 

  • Pourquoi migrer de framework si ceux de base sont proposé par Angular ? 🤔

 

Et bien pour deux raisons :

  1. Jest est vraisemblablement plus rapide que ses concurrents pour effectuer ses tests, car ils peuvent s’exécuter en parallèle. Vous gagnez donc au change, au fil du temps que votre application se développe.
  2. La seconde est que même si on créer à première vu un site web, il a néanmoins pour but d’être utilisé sous forme d’application bureautique via Electron. Les framework de test cité plus haut sont formidable pour tester des sites web. Cependant, comme on fait appel à des fonctions de l’API de Electron, on ne peut ouvrir notre application Electron convenablement sur notre navigateur favori. Ceux-ci ne vont donc être utile que vous du test unitaire, mais on peut dors et déjà oublier les tests e2e. C’est pour cela que Spectron est idéal, puisque développé pour tester des applications conçu sous Electron.
  3. Donne la couverture de code couvert par les tests
  4. Pas besoin d’un navigateur web pour exécuter les tests, tout se fait depuis la console
  5. Réalisation de ‘snapshot’, afin d’assurer que l’on ait pas de régression d’un point de vue UI

 

Jest

C’est le moteur de test développé par Facebook. Pratique, car tourne sur Angular, React, Vue.

 

Spectron
Spectron wrapper de WebDriverIO et Selenium

C’est un wrapper qui embarque à la fois Selenium, et WebDriverIO.

  • Selenium est un framework de test, qui permet de réaliser des opérations sur le navigateur web.
  • WebDriverIO quant à lui, est un autre framework de test qui reprend l’API de Selenium de façon customisé, écrit en javascript et exploitable par NodeJS. Il va ainsi ajouter des fonctionnalités de binding. On va pouvoir réaliser des opérations de click de souris sur des éléments, récupérer des champs de valeur, naviguer dans notre application, etc. Concrètement, on va pouvoir reproduire une utilisation du logiciel par un vrai utilisateur, mais en ligne de code.
  • Spectron, enfin, va ajouter des fonctionnalités pour avoir accès à l’ensemble de l’API de Electron

 

Optionnel : bibliothèque d’assertions

Lorsque on effectue des tests, on compare un état souhaité, avec l’état réellement obtenue lors de l’utilisation de l’application. J’utilise la librairie de base de NodeJS, à savoir assert. Simple et facile d’utilisation. Mais il est vrai que certains préférerons d’utiliser des styles d’écriture BDD ou TDD. Chai est une librairie que je recommande, qui permet de faire cela, tout en poussant les fonctionnalités de comparaison pour avoir des tests encore plus poussé.

Exemple de style que vous pouvez rencontrez, pour faire une comparaison de base :

  • Should : foo.should.equal(‘bar’);
  • Expect : expect(foo).to.equal(‘bar’);
  • Assert : assert.equal(foo, ‘bar’);

 

Spectron & Jest : utilisation

Installation

On commence par installer les modules nécessaire, en dépendance de développement via le gestionnaire de packets NPM :

Jest : npm install –save-dev jest

Auto complétion Jest : npm install –save-dev @types/jest

Spectron : npm install –save-dev spectron

 

/!\ Attention /!\

Veillez à bien respecter les versions entre Electron et Spectron, ou vous risquez d’avoir des soucis de compatibilité :

Electron Version Spectron Version
~1.0.0 ~3.0.0
~1.1.0 ~3.1.0
~1.2.0 ~3.2.0
~1.3.0 ~3.3.0
~1.4.0 ~3.4.0
~1.5.0 ~3.5.0
~1.6.0 ~3.6.0
~1.7.0 ~3.7.0
~1.8.0 ~3.8.0
^2.0.0 ^4.0.0
^3.0.0 ^5.0.0
^4.0.0 ^6.0.0
^5.0.0 ^7.0.0
^6.0.0 ^8.0.0
^7.0.0 ^9.0.0
^8.0.0 ^10.0.0

 

Configuration

On va créer un fichier de configuration pour jest, jest.config.json, à la racine de notre projet :

  • testMatch : définit une regexp pour matcher le nom des fichiers de tests. Ici, on garde les fichiers dans le dossier /e2e/,  et qui contient le mot .e2e. ou .unit. et qui est un fichier TS ou JS

 

Ensuite, on va ajouter un nouveau script pour automatiser le lancement de nos tests, dans notre fichier package.json :

  • config : pour renseigner la configuration crée précédent
  • runInBand : lancer les tests de façon séquentiel
  • detectOpenHandles : autorise Jest à fermer une session d’un test automatiquement si celui-ci ne se termine pas correctement, afin de continuer les tests

 

Squelette de base d’un test

Voici le template de base pour réaliser un test :

  • describe : c’est le mot clé pour définir un groupe de test
  • beforeEach : permet de retourner une application lancé a chaque début de test
  • afterEach : permet de fermer notre application une fois un test exécuté
  • it : mot clé pour définir un test

Vous pouvez observer la mise en place d’un timeout par Jest, mais aussi dans la définition de notre application. Cela permet de laisser un peu de temps à notre application pour s’ouvrir, avant de pouvoir l’utiliser.

L’ensemble des interactions possible via WebDriverIO sont disponible sur leur page de leur API.

 

Le code est exécuté de façon asynchrone. Vous allez donc devoir les rédiger soit en utilisant async/await, ou en utilisant des promesses. Chacun ses préférences, même si je trouve le code avec des async/await bien plus lisible et compréhensible.

 

Exemple de test

Je vous donne quelques exemple de tests simples, pour vous donnez des idées. Vous verrez les tests les plus simple à savoir cliquer sur des bouttons, récupérer des valeurs de champs de texte, accéder à l’API de Electron…

 

Vérifier que les outils de développement de Chronium ne sont pas ouvert 

 

Lire le contenu d’un champ texte

 

Vérifier la navigation entre module et composant

 

Tester l’application en plein écran

 

 

Conclusion

Spectron est la librairie officiel pour tester des applications sous Electron.

formation electron transpilation tsc Cours logiciel - Electron

Chap 7 : Backend en Typescript ( transpilation via…

Nous avons vu précédemment comment build et package l’ensemble de notre application en un .exe ou un installateur, si on souhaite le distribuer dans le chapitre précédent.

Je pensais avoir déjà fait un rapide tour d’Electron en 6 chapitres, mais à force de l’utiliser je pense pouvoir ajouter quelques chapitres supplémentaires qui pourrait bien vous servir et faciliter le développement autour de ce génial framework.

 

 

Objectif

  • Diviser les fonctionnalités de notre unique fichier du backend (main.js) en une multitude de fichiers
  • Permettre d’écrire le backend en Typescript et plus Javascript via un transpileur (TSC)
  • Pouvoir transpiler en instantané ( hot reload )

Le code source concernant ce chapitre est disponible sur mon Github.

 

 

Passage du Javascript vers le Typescript

Pour le moment, nous avons l’ensemble de notre application du frontend écrit via Angular en Typescript, mais le backend en Javascript. Il faut dire que le TS apporte beaucoup au JS traditionnel, et c’est pour cela que j’ai décider de migrer le backend. Il faut savoir que seul le pure javascript est compréhensible de nos navigateurs.

 

  • Comment Angular peut-il alors faire du frontend alors que l’on écrit notre application en TS ? 🤔🤔

 

De façon invisible, nous avons Webpack, planqué dans Angular, qui nous créer notre bundle en effectuant une multitude de transformation de nos fichiers, donc une que l’on va voir maintenant, est qui est la phase de transpilation. Celui-ci va transpiler l’ensemble de nos fichiers TS. Un mot bien complexe qui n’est rien d’autre que la conversion des fichiers TS en JS.

 

Script NPM pour la transpilation du typescript

Je suis parti sur TSC, qui est le transpiler de base de Typescript, car il est très simple d’utilisation, pas besoin de s’embêter avec un tas de paramétrage pour transpiler deux pauvres fichiers TS. Si vous souhaitez vous lancer dans des utilisations plus poussés, renseignez vous auprès de Webpack ou encore Babel.

 

On ajoute premièrement à notre package-json un nouveau script pour nous permettre d’appeler TSC :

  • backend-serve : nom du script
  • –project : argument pour fournir un fichier json de description pour le transpiler
  • –watch : argument pour compiler à la volé, dès qu’une sauvegarde de code est détecté

 

Si vous souhaitez transpiler seulement une fois sans avoir besoin du rechargement à la demande, vous pouvez supprimer l’argument ‘–watch’.

 

Une fois le script ajouté, on va créer un nouveau fichier comme vous avez pu le lire précédemment, tsconfig.backend.json, qui va nous permettre de décrire comment nous souhaitons transpiler nos fichiers TS.

Les arguments les plus importants sont :

  • include : on liste ici l’ensemble des fichiers TS que l’on souhaite transpiler
  • baseUrl : décrit la base du projet. On s’en servira plus tard lorsque je parlerais d’import de module en absolue ou relatif.

 

Ré-écrire son Main.js en typescript

Le but va être de ré-écrire son fichier d’entrée de notre application Electron, Main.js, en une version typescripté. Ouais je sais que ce mot existe pas, et alors c’est mon blog !😋

La ligne 5 représente un import de module pour les fichiers JS, la ligne 6 la méthode pour les fichiers TS

On va copier notre fichier Main.js et en faire un nouveau Main.ts. Vous risquez d’avoir quelques erreurs de lancé par votre linter, rien de bien complexe à modifier, vous devriez vous en sortir sans grand soucis. Un exemple dont vous pouvez avoir est la façon dont vous devez importer vos modules.

 

 

Je vais néanmoins quand même vous accompagner pour vos premières classes, car vous risquez d’avoir un petit soucis 😜

 

 

Architecture du backend

Jusqu’à présent nous n’avions qu’un seul fichier pour le backend, pour la gestion du cycle de vie de notre application. Au fur et à mesure des fonctionnalités que vous allez ajouter au backend, il se peut que vous souhaitiez éclater ce fichier ‘main.js’ en une multitude d’autres afin d’avoir une plus fine granularité, et ainsi d’améliorer l’extensibilité du code dans le futur. Je vous propose de suivre l’architecture suivante :

 

On va ajouter les deux classes suivantes :

  • StorageManager : on va lui déléguer l’ensemble des fonctionnalités de Main.js qui touche l’ensemble des serialization des données du module electron-store
  • CommunicationManager : on va lui déléguer l’ensemble des fonctionnalités de Main.js qui touche à l’échange d’informations entre le render et le main process, soit l’ensemble des fonctions du module IPC.

 

Erreur du loader/resolveFilename

Vous avez enfin une belle architecture, écrite en TS, et vous avez TSC de configuré. Aucune erreur sur l’ensemble de vos consoles, super, vous pouvez lancer Electron… et BIM ! Une belle erreur devrait apparaître, comme quoi vos nouveaux composants fraîchement crées ne sont pas trouvable 😒. Tsc étant un transpiler simple, il ne fait pas la liaison entre les composants lorsque on utile des imports absolue. Cependant si vous utilisez des importation de module avec des liens relatifs, vous n’aurez pas de soucis. Cependant, l’écriture de ces imports rend leur lecture complexe, en voici un exemple :

import * as test from ‘../../../../../../monModule’;

 

  • Mais pourquoi la console de TSC ne m’a pas indiqué d’erreur lors de la transpilation, mais seulement au moment de lancer Electron ? Car nous l’avons paramétré dans le fichier tsconfig.backend.json, avec l’argument ‘baseURL’ souvenez vous.

 

Si j’ai fais ce tutoriel avec TSC, c’est qu’il existe néanmoins des solutions, même si je vous avoue m’être bien cassé la tête sur ce problème. Pour résoudre ce soucis de chemin dans les require, vous avez deux petits modules à la rescousse disponible sur NPM.

 

Méthode 1 – La plus simple & basique

Son principe est simple, il va ajouter le répertoire parent de plus haut niveau dans le module de recherche de chemin de Node.

 

Il suffit d’installer le module suivant :

npm install app-module-path –save

C’est la méthode la plus simple, car il suffit d’ajouter une seule ligne de code, au début de notre fichier main.ts :

Pratique, car fonctionne lors du build, mais aussi en mode hot-reload durant le développement.

 

Cependant, si vous souhaitez seulement tester un fichier en particulier, une classe par example, et donc ne pas lancer votre application entière via le main.ts (faire simple un => node maclasse.js), cela ne fonctionnera pas car ayant ajouté le code précédent dans le main.ts, celui-ci ne sera pas lu. Pour cela vous êtes soit obligé de toujours lancer le main.ts depuis node pour que l’ensemble des imports soient modifiés, soit ajouter ce code dans l’ensemble des classes, ce qui peut vite devenir lassant. C’est pour cette raison là que je vous conseille la méthode 2.

 

Méthode 2 (recommandé) – Un poil plus complexe, mais plus flexible

Un second module vient à notre rescousse mais se comporte tout autrement. En effet, il va aller modifier les imports absolue de chaque fichier pour les remplacer par des liens absolue lors du build, dans les fichiers transpilé .js. Terriblement efficace, et pas bien plus complexe en ne nécessitant qu’une petite étape supplémentaire de configuration.

On installe ce module via:

  • npm install ttypescript --save
  • npm install @zerollup/ts-transform-paths --save

Héhé, je vous en fait installer un second en cachette car nous allons avoir besoin d’un wrapper, ttypescript, qui va nous permettre d’utiliser des plugins de transformation qui sont supporté dans notre fichier de configuration des options de compilation, disponible dans le fichier tsconfig.json.

 

Premièrement, on va modifier notre script NPM du fichier package.json de tout à l’heure pour qu’il utilise ttypescript que l’on vient d’installer :

 

On va ensuite modifier notre fichier de configuration qui permet de transpiler le backend, tsconfig.backend.json, afin de lui ajouter notre transformateur dans l’option ‘plugin’ pour qu’il puisse ré-écrire les imports :

Et on lui dit dans l’argument ‘paths’ de récupérer tout les fichiers à la base du projet et de les importer tel quel.

 

C’est finit, vous n’avez plus qu’a builder le backend depuis la console, avec notre script npm via la commande :

npm run backend-serve

Pour tester si tout fonctionne lancer le serveur de développement Angular avec:

npm run angular-serve

Ainsi que electron via :

npm run electron-serve

 

Mise à jour de la configuration du build

Afin de pouvoir continuer à builder, packager et distribuer votre application avec le module electron-builder, n’oubliez pas de modifier votre configuration de build disponible dans le fichier electron-builder.json ( ou dans votre package.json si vous n’avez pas dissocié les fichiers de configuration ). En effet, venant de modifier le backend en une multitude de nouveau fichiers TS et JS, nous devons mettre à jour notre configuration afin que celle-ci les prennes en compte dans le packaging de l’application. Pour cela, on va ajouter un nouvel item dans l’argument ‘files’, afin d’ajouter nos fichiers javascript précédemment transpilé :

 

Conclusion

On vient de voir la façon la plus simple pour pouvoir transpiler son backend Electron via TSC et un transformateur, pour résoudre les liens des imports absolue en relatif. Cela va nous permettre d’utiliser le typage et ainsi d’avoir un code source plus rigoureux grâce à Typescript.

 

Cours logiciel - Electron

Chap 6 : Build, package et distribution (installateur) de…

Nous avons vu au chapitre précédent comment améliorer l’UI de notre application avec un système permettant à l’utilisateur de choisir son thème. Cela se fait beaucoup actuellement sur les applications pour reposer notamment les yeux lors d’une utilisation nocturne. Nous avons aussi vu comment sérialiser simplement et rapidement des données utilisateurs concernant les préférences et paramètres de l’application via de simples fichiers JSON.

Le code source concernant ce chapitre est disponible sur mon Github.

 

Principe global

Dans ce sixième et dernier chapitre de cette série consacré à l’utilisation de Electron, nous allons voir comment packager notre application afin de la distribuer. Pour cela nous allons utiliser le très bon module Electron-builder pour créer nos installateurs. On va installer ce module en tant que dépendances de dév :

  • npm i electron-builder -g

 

Nous allons devoir réaliser deux principales étapes afin de créer notre installateur :

  1. Builder notre application Angular en mode production,
  2. Packager le précédent build via Electron-builder.

 

Génération du build Angular en mode prod

Cette première étape va consister à créer un bundle de notre application. On va demander à Angular de builder notre application en mode production afin de compiler l’ensemble de nos composants, contrôleurs et pages web avec nos modules NPM, afin de passer d’un dossier de quelques centaines de Mo à un build ne pesant que quelques Mo.

Nous allons devoir effectuer quelques modifications de code, car actuellement on ne fait que build notre application dans un environnement de développement via notre serveur local.

 

Chargement de la page d’accueil

Pour le moment on demandait à Electron de charger à l’initialisation de la fenêtre, le rendu du serveur local de Angular via :

win.loadURL('https://localhost:4200/')

On va ajouter du code permettant de demander le chargement de index.html de notre build dorénavant :

On va demander de charger un fichier et non plus une URL, en indiquant via le paramètre protocol. Le chemin correspond au fichier index.html dispo dans notre build, situé dans le dossier ‘dist’ de Angular. Le paramètre slashes est extrêmement important pour Angular, afin de permettre le routage des diverses pages au sein de notre application.

 

Activer le Hash (#)

Etant donnée que l’on crée une SPA ( Single Page Application ), on peut observer des # dans notre URL, mais pas pour tout le monde, puisque Angular le cache dans les dernière version, et cela pose problème.

En effet avec le serveur de dév, tout fonctionne bien. Mais une fois passé en mode production, on arrive plus à afficher nos pages web correctement, car l’URL est faussé sans notre #. Pour cela, on va devoir le spécifier dans notre module principal de routing, d’utiliser le hash :

 

Base des liens

On va aller modifier la base de l’ensemble des liens de notre application, disponible dans notre index.html afin qu’il corresponde avec Electron :

<base href="./">

 

Cible de build

Dans le fichier de configuration de build de Angular, tsconfig.json, on va modifier la ligne suivante :

  • « target »: « es2015 »

par :

  • « target »: « es5 »

 

Génération du build

Dernière étape, on va générer le build Angular via :

  • ng build –prod

Le build est dispo sous /dist.

 

Pensez à tester ce build de production directement avec Electron avant de passer à l’étape suivante, via la commande :

  • electron .

Sans utiliser notre arguments –devTools, on demande à electron de tester notre build précédemment crée et non le serveur de développement de Angular.

 

Tout fonctionne pour moi, on peut passer à l’étape finale 😎

 

/!\ Attention à bien vérifier les liens vers vos assets, qu’ils soient bien relatif et non absolue, sinon vous risquez d’avoir des soucis et ne seront pas trouvé dans votre app Electron !

 

Package du build via Electron-builder

Vous avez de disponible quelques modules pour vous permettre de vous faciliter la vie pour créer votre installateur. En voici les principaux :

Comparatif des modules de build/package les plus populaires

Je vous propose de partir sur le plus populaire du moment de Github, à savoir Electron-builder. Mais vous pouvez partir sur celui qui vous fait plaisir, je n’ai pas essayé les autres mais je présume qu’ils doivent chacun faire le boulot !

 

Du coup avec le notre de module, c’est plutôt simple. On a juste à définir de nouveaux comportements dans notre fichier main.js. Je vous montre la spécification minimal, la plus simple pour générer un installateur. De nombreuses autres options sont disponible sur le site de Electron-builder, que cela soit pour faire un build Window, Linux ou macOS.

appId : nom de l’application

compression : définit le niveau de compression des données de notre application dans l’installateur

win : on définit ici les options pour un build pour window, à savoir la cible ainsi que le fichier d’icone pour notre application

electronDowload : permet de mettre en cache les utils et dépendances nécessaire à Electron builder afin de compiler notre installateur

directories : on définit le dossier d’output pour notre installateur

nsis : c’est la cible concernant un build pour window, on définit les options ici de l’installateur. On lui spécifie que on veut laisser le choix à l’utilisateur pour installer sur une session ou en global, la possibilité de choisir son dossier d’installation ainsi que de supprimer ou non les données de l’application en cache une fois celle-ci de supprimé

files : c’est ici que l’on spécifie à Electron builder les fichiers nécessaires au bon fonctionnement de notre application. On lui donne notre point d’entrée de notre app qui est main.js, ainsi que notre package.json ou l’ensemble du fonctionnement y est spécifié, et enfin le build de production généré par Angular précédemment

 

Pour générer l’installateur, ouvrez votre console dans le dossier du projet et tapez :

  • electron-builder

Il va télécharger les dépendances et utilitaires nécessaire pour créer l’installateur. Vous pouvez lui spécifier des arguments pour définir quelle plateforme et quelle architecture cible vous souhaitez pour votre/vos installateurs.

Dans votre dossier de sortie de Electron builder, sous /distElectron, vous aurez à la fois un dossier avec l’ensemble de votre application buildé et packagé prêt à fonctionner ( on peut appeler ça une installation dite portable, d’un simple copié/collé vous partagez votre app) ainsi que d’un installateur au format .exe traditionnel.

 

Astuce : builder en mode offline

Electron-builder va descendre certaines extension pour réaliser le build. Si vous souhaitez réaliser des builds en mode offline, sur un pc n’étant pas connecté à internet, vous pouvez mettre une variable d’environnement pour forcer le cache de electron builder dans le dossier spécifique de votre choix :

  • set ELECTRON_BUILDER_CACHE= »votre_dossier »

 

Vous aurez ainsi dans ce dossier les éléments suivants :

ELECTRON_BUILDER_CACHE :

  • votre_dossier
    • nsis
      • nsis-x.x.x.x
      • nsis-ressources-x.x.x
    • winCodeSign
      • winCodeSign-x.x.x

 

Vous aurez plus qu’a récupérer ce dossier, et de les déposer via usb sur votre nouvel ordinateur qui ne dispose pas d’un accès internet. N’oubliez pas de re-set la variable d’environnement sur ce dernier pc pour lui indiquer le bon chemin pour accéder à ce même dossier.

 

Conclusion

On arrive avec de sixième chapitre à la fin de la série consacré à comment débuter sur Electron. Vous êtes désormais capable de :

  • Initialiser un nouveau projet, développer avec un serveur de dév en local avec hot reload du frontend & backend,
  • Créer votre première fenêtre avec persistance des données utilisateurs,
  • Gérer la communication entre render & main process, gérer la communication entre composant de Angular,
  • Builder un projet Angular, packager votre application Electron.

 

Cours logiciel - Electron

Chap 5 : Customisation de l’UI (light & dark…

Nous avons vu au chapitre précédent comment créer notre éditeur de texte, comment communiquer du render au main process via le module IPC afin d’interagir avec les fichiers disques via les API de NodeJS.

Pour ce cours-ci nous allons nous consacrer sur une fonctionnalité apprécié en ce moment, à savoir comment avoir un thème sombre et clair, et comment enregistrer ces données-ci afin de les récupérer à chaque ouverture du logiciel. Une rapide ouverture à la programmation réactive Observer/Observable via la librairie RxJS afin d’implémenter une fonctionnalité pour améliorer l’UX de notre logiciel, afin de renseigner le nom du fichier texte actuellement ouvert par l’utilisateur.

Ce cours sera donc principalement consacré à l’amélioration de l’UI pour l’utilisateur.

Le code source concernant ce chapitre est disponible sur mon Github.

Résultat du cours

 

Mise en place du système de persistance

Je vous propose d’ajouter une fonctionnalité, permettant de sauvegarder l’état du thème choisit, pour qu’il puisse être à jour à chaque lancement de l’application et que l’on ne soit pas obligé de le re-sélectionner. D’une manière général, je vous propose un moyen simple afin de sauvegarder et charger des paramètres utilisateurs en cache.

Pour sauvegarder des données, vous pouvez très bien créer une base de données plutôt traditionnel afin de stocker vos informations nécessaire au fonctionnement de l’application. Mais pour notre application qui reste extrêmement minimaliste, je vous propose la sérialisation des data dans un simple fichier JSON. Si vous souhaitez néanmoins rester sur une BD traditionnel, vous devriez regarder vers SQLite database, ou encore IndexedDB sur NPM.

 

Première chose, on va installer un simple module nous permettant de gagner du temps quand à la persistance de fichier JSON.

  • npm install electron-store –save

Souvenez vous que nos fichiers seront disponible dans le dossier %Appdata% de votre ordinateur, dans le dossier du nom de votre application.

On commence par vérifier si notre fichier JSON de sauvegarde existe au préalable sur l’ordinateur. Si celui-ci existe on ne fait rien en particulier. Dans le cas contraire, on va initialiser les valeurs des nos couples Clés/Valeurs. On souhaite avoir comme paramètre sauvegardé, le type de thème sélectionné ( Light, Dark ou Custom ) mais aussi les codes couleurs hexadécimal de nos différentes parties de notre application customizable, via le thème ‘Custom’. En effet, autant les thèmes Light et Dark sont pré-défini au sein de l’application et non modifiable, autant le thème Custom est modifiable lui.

On ajoute dans notre main process de Electron les bons imports qui vont bien :

L’argument ‘name‘ représente le nom du fichier JSON de sauvegarde, lors de la création de notre objet ‘storage‘.

 

On définit ensuite une fonction qui sera appelé dans notre fonction ‘createWindow‘ :

Comme je vous ai dit plus haut, si le fichier ‘settings.json‘ existe déjà, on ne fait rien. Dans le cas inverse, on va le créer et initialiser :

  • SETTINGS : clé
    • THEME_TYPE : clé, contient le type de thème à appliquer au lancement de notre app
    • CUSTO_PALETTE : clé, contient d’autres clés qui sont nos variables CSS avec leur code couleur hexadécimal qui leur sont associé

 

Thème clair & sombre

Il existe plusieurs façon de créer son propre système de thème pour son application. Nous allons voir une méthode très simple qui utilise les variables CSS. Au lieu d’affecter une couleur en dur à un composant HTML via son fichier CSS ( code en hexadécimal ou RGB ), on va désormais lui affecter une variable. C’est celle si que l’on va aller modifier selon no thème. Cela nous permet ainsi de bind plusieurs couleurs au même composant. Je vous propose de créer un thème clair, foncé, et un custom, auquel on pourra lui affecter au sein même de notre application une couleur modifiable à la volée.

 

Création des différents modèles de thèmes 

Premièrement, on va créer  une énumération définissant nos différents type de thème que l’on peut choisir:

 

Ensuite, nous  allons créer une interface permettant de créer des objets du même type :

 

Dans le même fichier précédent, on va maintenant créer 3 objects correspondant à nos 3 thèmes. Nous allons leur affecter un type ( Light, Dark ou Custom ) et leur définir l’ensembles des propriétés CSS que l’on souhaite modifier. Les propriétés CSS ont été réduite volontairement pour gagner en lisibilité, vous pouvez retrouver l’ensemble des propriétés du projet via son dépôt Github. Si on souhaite modifier par exemple seulement la couleur de fond de notre application :

Le mot clés export nous permet d’y accéder en dehors de ce fichier.

 

Mise en place de l’interface pour la sélection du thème

Pour la vue de notre page de paramètres, faisons quelque chose de simple. On va disposer d’un groupe de bouton radio, permettant une sélection unique du thème. Cela nous rampement de choisir entre Light, Dark et Custom. Les deux premiers thèmes ayant des couleurs définit dans notre application, seul le Custom pourra être modifiable, histoire de laisser un maximum de liberté à l’utilisateur dans le choix de ses couleurs. Pour la vue, rien de bien complexe :

On ajoute juste une condition, dans le cas ou l’utilisateur choisit le thème ‘Custom’, on affiche un sélecteur de couleur pour chaque item modifiable de notre application. Pensez d’ailleurs à installer ce module que j’apprécie fortement, un color picker simple qui permet de choisir une couleur en héxadecimal, en RGB ou via un arc-en-ciel de couleur, et qui propose une multitude de fonctionnalités via son api, installable via :

  • npm install material-community-components –save

Petit aperçu du module :

Plutôt sympa non ?😎

 

Passons maintenant au contrôleur de notre page de paramètres. Nous devons définir des attributs pour lier nos boutons précédemment expliqués :

  • availableTheme : Tableau contenant les thèmes disponible à la séléction, responsable de la création des boutons radio
  • aliasTypeTheme : cet alias est un bind à notre énumération précédente, qui contient les trois type de thèmes. Cela nous permet de pouvoir faire dans la vue notre comparaison, et afficher le color picker si et seulement si l’utilisateur à sélectionné le thème Custom
  • activeTheme : c’est le thème actuellement activé

 

Concernant le constructeur du composant, on va créer une instance de ElectronService, permettant de discuter du render process au main process et vice versa :

On initialise nos thèmes disponible pour créer nos boutons radio.

 

Système pour initialiser un thème au démarrage de l’app via Electron-store

On va déléguer la gestion des préférence utilisateurs à un service, un singleton. Créons le via la CLI de Angular :

  • ng generate service ThemeManager

On va lui définir un attribut correspond au thème actif, et un second correspondant lui aussi au thème actif, mais qui sera un BehaviorSubject ( le but de celui-ci et de mettre à jour le thème actif au lancement de l’application , lorsque celle-ci chargement au démarrage les préférences de l’utilisateur) :

 

Concernant le constructeur du service, on va créer une instance de ElectronService permettant de contacter le main process :

On initialise par des valeurs random nos deux précédents attributs (je vous l’accorde niveau QUALITÉ du code, on a fait mieux hein 😅). et on envoi une notification au main process sur le canal ‘loadUserSettings‘.

 

On va définir dans le main process la méthode permettant de lire dans notre fichier JSON de sauvegarde, les données des préférences (définit par notre clé ‘SETTINGS’, et de l’envoyer au render process via le cannal ‘responseLoadUserSettings‘:

 

On réceptionne dans le thème manager les données d’initialisation envoyé par le main process :

On actualise notre thème actif, la palette de couleurs pour le thème ‘CUSTOM’,  et on met à jour notre BehaviorSubject pour mettre la vue à jour concernant le thème actif, et enfin on appelle une méthode permettant d’appliquer notre thème :

On parcours les variables CSS du thème actuel, et on va les appliquer à notre document. Voilà, notre thème est appliqué au démarrage ! 😄

 

La dernière étape consiste à mettre à jour le modèle de nos boutons radio suite au chargement du thème initial. On ajoute une fonction dans le constructeur du composant de la page paramètres, afin qu’il soit notifié dès que le thème actif de notre service ThemeManager change. Voilà pourquoi je l’ai définit en tant que Observable, pour lui attacher un observateur. On va pouvoir subscribe a ce Subject de la façon suivante :

 

Système pour appliquer le thème courant

Maintenant que au lancement de notre application nos préférences sont lues et appliqués, on souhaite pouvoir changer de thème durant l’utilisation de notre application. On retourne sur le contrôleur de notre page de paramètre, et on ajoute la fonction suivante :

Cela va nous permettre de mettre à jour le thème actif pour nos boutons radio mais aussi de l’appliquer, via le ThemeManager.

 

Système pour sauvegarder le thème courant

Nouvelle fonctionnalités qui peut être cool, c’est de pouvoir enregistrer l’état courant de notre application, concernant le thème actif actuellement. Très simple, on va ajouter une seule ligne à la méthode expliqué juste avant, changeTheme() disponible dans le contrôleur de notre page ‘SETTINGS‘ :

Cela permet à chaque changement de thème, ou de couleur sur le color picker pour le thème CUSTOM ( car cette méthode d’actualisation est aussi appelé lors d’une modification de couleurs ) d’envoyer une notification à notre main process sur le canal ‘saveSettings‘, avec notre thème actuel en data.

Dans le main process, nous ajoutons une méthode permettant de réceptionner le thème actuel :

Et on met à jour notre fichier JSON contenant nos préférences utilisateurs, via Electron-store.

 

 

Indication de la page en cours d’exécution

Vous allez avoir besoin d’un nouveau module, permettant de faire de la programmation réactive :

  • npm install rxjs –save

Histoire d’améliorer l’interface utilisateur, je vous propose d’ajouter au centre de notre footer, une indication pour rappeler à l’utilisateur sur quel page il se situe au sein de notre application. Pour cela, on va définir une énumération contenant l’ensemble des pages de notre application :

 

Ainsi lorsque l’utilisateur va changer de page via les boutons de navigation situé en haut de notre application, on demandera une mise à jour du footer. Et pour cela, on va avoir besoin d’un service. On va créer ce service depuis la CLI de Angular :

  • ng generate service FooterUpdateService

 

Ce service va nous permettre d’échanger des données entre nos différents composants. Il se compose de la façon suivante :

On définit un BehaviorSubject. Ceci est un type de la librairie RxJs, qui propose de réaliser de la programmation réactive. Cela est grosso modo de la programmation qui suit le paradigme Observable et Observer. Ce menuStateSubject est un observable. Le ‘behavior‘ indique que c’est un observable, qui sera initialisé dès sa création avec un état pré-défini. Vous pouvez le voir dans le constructeur du service, on lui définit l’état HOME. Si vous souhaitez de pas lui définir d’état en particulier à sa création, vous pouvez utiliser simplement un Subject à la place du BehaviorSubject.

On a une première méthode, updateMenuStateSubject, permettant de lui envoyer un nouvel état.

La méthode getMenuStateObservable permet de renvoyer notre observable, nous l’utiliserons juste après.

 

Le but de ces observables, et d’y attacher des observateurs, ou juste de pouvoir subscribe au sujet. Cela permet de notifier à chaque changement d’état de notre Observable,  ses observateurs et de pouvoir faire des actions en conséquence.

 

On va ajouter dans le contrôleur de notre Header, une fonction permettant de mettre à jour l’état de notre Observable, définit dans le service précédent :

N’oubliez pas d’ajouter au constructeur de notre contrôleur Header,  l’appel au singleton de notre service via ‘public footerService: FooterServiceUpdate‘. On ajoute un argument à cette fonction, du type de l’énumération précédemment crée, afin de déterminer quelle page on ouvre.

 

On ajout ensuite le bind (click) dans notre vue sur chacun de nos boutons, qui nous permettent de changer de page. Ils permettent dorénavant de mettre à jour notre observable :

 

On ajoute dans la vue du footer une variable permettant d’afficher le contenu d’une variable qui sera définit dans son contrôleur :

 

On va ajouter dans le contrôleur du footer, l’attribut précédemment utilisé pour l’affichage de l’état courant du menu :

 

Et voilà le résultat !

Résultat de l’actualisation du footer

 

 

Conclusion

Nous venons de voir quelques pistes afin d’améliorer l’UI pour notre application, ainsi qu’une piste pour sauvegarder les préférences de l’utilisateur. Nous aurons aussi vu une rapide approche sur la bibliothèque RxJS, permettant de suivre le paradigme Observable/Observer.

 

Le 6 eme et dernier chapitre de cette formation est consacré au build & package de notre application, afin de pouvoir la distribuer comme n’importe quel logiciel.

 

Cours web frontend - Angular 8

Chap 3 : Structure d’un application Angular

Nous avons vu au chapitre précédent comment générer le squelette de base d’une application sous Angular 8. Nous avons vu une multitude de fichiers crées lors de cette génération effectue par Angular/Cli.

Sont-ils tous réellement utiles ? A quoi correspondent-ils ? Je vais vous en présenter les principaux à connaître.

Il faut savoir que Angular permet de créer une multitude de brique logiciel ( composant, service, classe…  ) que l’on va assembler entre eux de façon organisé et distincte ( module ).

 

Structure globale

/e2e

Ce dossier va permettre de rédiger divers test end to end par le framework Protractor

 

/package.json

C’est un fichier json qui va contenir la description de l’ensemble des modules NPM utilisé pour notre application. Vous aurez le choix d’installer ou d’update certains packet en comparant ce fichier. Utilise aussi pour gérer les dépendances nécessaires entre packet.

 

/angular.json

Fichier de configuration qui contient certains hyper paramètres important, tel que le dossier de sortir pour les builds de production, les dossiers contenant les fichiers de styles ou encore les assets, la page HTML principal à afficher, etc.

 

/src

Ce dossier va contenir l’ensemble de nos fichiers sources de notre application

 

Module et composition

Un module est un conteneur, un building block. Il permet de créer des packages distant d’un point de vue fonctionnalité. Par exemple pour un site web simple comme le bon coin, on peut avoir un module pour la gestion des annonces, et un module pour la gestion de l’authentification des comptes.

Ces modules nous apportent une plus fine granularité au sein d’un projet. Cela permet plus tard, d’améliorer l’extensibilité et la maintenabilité du code pour l’ajout de nouvelles fonctionnalités.

Vous pouvez créer un module via la commande Cli suivante :

  • ng generate module [nom du module] –routing

L’option –routing est optionnel, mais nous facilite la tâche. Nous le verrons juste après.

 

Cette commande va nous créer plusieurs fichier. On imagine que notre module s’appelle APP.

  • app.module.ts : c’est le fichier centrale de notre module. On y définit l’ensemble des imports qui seront utilisé dans notre module (librairies NPM), on y définit l’ensemble des composants qui y seront déclaré, mais aussi des services.  C’est quelque peu comme les fichiers H/HPP en C/C++.
  • app-routing.module.ts : c’est le fichier responsable de la navigation entre composant, et donc entre les vues.

 

Component et composition

Un composant est une entité dans angular. Il prend la forme que vous lui donnez. Cela peut très bien être une page d’accueil en entier, comme une simple barre de navigation servant de menu. C’est à vous de choisir encore une fois la granularité que vous donnez aux objets de votre application.

 

Vous pouvez créer un composant via la commande Cli suivante :

  • ng generate component [nom du composant]

 

Cette commande va nous créer plusieurs fichier. On imagine que notre module s’appelle comp1.

  • comp1.component.css : c’est la feuille de style de notre component
  • comp1.component.html : c’est la feuille qui correspond à la partie graphique, la vue
  • comp1.component.spec.ts : c’est un fichier permettant de réaliser des tests, qui seront automatisé avec Protractor
  • comp1.component.ts : c’est le contrôleur de notre component. Il va nous permettre d’y ajouter des fonctionnalités entre la vue, les boutons, la base de données, etc.
Cours web frontend - Angular 8

Chap 2 : Initialisation de notre première application

On a vu comment installer les dépendances nécessaires à une application web dans le chapitre précédent.

On va maintenant voir comment générer le squelette de base d’une application en Angular 8.

Création de l’app

On va générer notre application avec la commande CLI suivante :

  • ng new NomdeL’app

 

CLI va nous demander plusieurs questions concernant la génération :

Angular routing : nous le verrons dans un prochain chapitre. Cela permet de gérer la navigation au sein de l’application. On ne va pas s’en servir dans le chapitre actuel, mais vous pouvez mettre Oui.

Choix des feuilles de style : CLI nous propose entre CSS, SCSS et Sass. Le CSS étant le plus commun, on va garder celui-ci. Sachez que le compilateur transformera le SCSS et Sass en CSS. Ces deux derniers permettent juste une écriture des styles de façon plus lisible et rapide. Ce choix n’est pas définitif puisque vous pourrez le changer à n’importe quel moment plus tard dans le développement de votre application.

Comparaison syntaxique entre 3 langages de style

Cli va nous générer des fichiers. Pas besoin de savoir l’utilité de chaque pour le moment, nous le verrons dans le prochain chapitre. On va se déplacer dans le fichier racine du projet :

  • cd NomdeL’app

Pour enfin lancer :

  • ng serve

Cette dernière commande va nous permettre de build notre application. Et celle-ci est pratique, puisqu’il suffira de changer une seule ligne de code dans notre projet, pour que le projet soit re-buildé automatiquement, et que l’on voit les modifications dans le navigateur en temps quasi-réel.

 

Vous n’avez plus qu’a lancer votre navigateur préféré et aller sur :

  • http://localhost:4200/

 

Eeeeeeeeeh TADAAAAAAA

Je vous l’accorde ce n’est pas ouf. Mais c’était rapide non ?

 

Avant d’aller plus loin dans  la customisation de notre application web, dans le prochain chapitre 3, nous ferons une halte pour comprendre l’ensemble des composants crées précédemment.

Cours web frontend - Angular 8

Chap 1 : Installation des pré-requis

Pour créer le frontend d’une application avec le framework Angular, il va nous falloir installer quelques dépendances nécessaires. Rassurez-vous, rien de bien long 🙃

 

Node.Js & NPM

Pour faire simple, c’est un framework en Javascript permettant de réaliser des serveurs pour le backend. On en a besoin puisqu’il va nous fournir NPM. C’est le gestionnaire de packet pour le web, comme NuGet pour le C#, ou encore PiP pour Python. Il va nous permettre d’installer pleins de librairies nous facilitant le développement de notre application.

 

Vous pouvez le récupérer sur son site https://nodejs.org/en/

Installer la version que vous souhaitez cela importe peu. Il va créer un dossier Node sur le disque C. Vous devrez rajouter ce dossier C:\ProgramFiles\Node\ au PATH des variables d’environnement de votre système d’exploitation, pour que nous puissions utiliser les alias dans la console.

On peut alors tester que tout fonctionne correctement :

C’est OK pour nous, on a bien Node.Js et NPM qui sont accessible.

 

Angular & Angular/Cli

La prochaine étape va être d’installer la librairie Angular. Mais pourquoi alors parler de Angular/Cli ? CLI est une interface de ligne de commande pour Angular, une sorte d’extension. Elle va nous permettre de faciliter la création d’une application Angular par la suite en créant à notre place toute sorte d’objets pré codés, nous permettant alors de gagner un certain temps.

Dans une console on va alors se mettre à la racine du projet duquel on souhaite créer, et exécuter :

  • npm i @angular/cli

 

Vous pouvez voir l’ensemble des packets installé via :

  • npm list –depth=0

L’attribut –depth est facultatif. Il permet de réduire l’arbre des dépendances de l’ensemble des packets pour y voir plus claire

 

Nous voilà OK pour le chapitre suivant, auquel on va pouvoir initialiser notre première application !