DĂ©couvrir Un Nouveau Framework : SolidJS đ§âđ»
Le monde du dĂ©veloppement Web est en perpĂ©tuelle Ă©volution, et voit apparaĂźtre de nouvelles librairies JavaScript (toujours plus intĂ©ressantes), jour aprĂšs jourâŠ
Cette annĂ©e (une fois encore), je me suis lancĂ© le dĂ©fi dâexpĂ©rimenter une nouvelle technologie. Le Web Ă©voluant constamment, il est important de se mettre Ă la page tous les 6 mois. Câest Ă lâissue des rĂ©sultats du dernier sondage âState Of JSâ, que jâai repĂ©rĂ© deux nouveaux frameworks que me semblaient prometteurs : AlpineJS x SolidJS
NB : Je suis passionnĂ©, jâai soif de connaissances, et rĂ©cemment jâavais envie dâapprendre quelque chose de frais, Ă lâimage de la dĂ©couverte de Svelte en 2019.
AprĂšs avoir lu deux ou trois documentations, et analysĂ© plusieurs dizaines de lignes de code, mon choix sâest trĂšs vite orientĂ©e vers SolidJS, notamment du fait de lâomniprĂ©sence du JSX, ainsi que de concepts similaires Ă mon outil de tous les jours, Ă savoir : React !
Dans cet article, je vais Ă©videmment parler de ce quâest SolidJS, mais surtout de la maniĂšre dont jâai apprĂ©hendĂ© ce nouveau framework dans une dĂ©marche dâapprentissage (de la thĂ©orie Ă la pratique). Je ne manquerais pas dâĂ©voquer les dĂ©pendances qui gravitent autour de son Ă©cosystĂšme. Enfin, nous verrons si ce dernier tient sa promesse de ârĂ©activitĂ© fineâ, tout en Ă©tant simple et performant.
SolidJS, câest quoi !?
NB : Avant dâentrer dans le vif du sujet, une brĂšve explication⊠Dans le cadre de travaux autour de la mise en place dâun rĂ©seau de pair-Ă -pair en JavaScript (article Ă venirâŠ), jâai souhaitĂ© disposer dâune interface / dâune application de contrĂŽle des actions relatives Ă un noeud (autre que Postman). PlutĂŽt que de dĂ©velopper cela Ă partir de bases dĂ©jĂ connues, jâai commencĂ© Ă apprendre plus en dĂ©tail ce quâest rĂ©ellement SolidJS, et Ă la mettre en oeuvre dans un projet dâampleur. Voici ma dĂ©marche dâapprentissage !
Tout comme une multitude de librairies JavaScript avant lui, SolidJS est un framework orientĂ© composants permettant de construire des interfaces Web. Bien que proche de React dans certains de ses concepts (et sa syntaxe), il se veut plus lĂ©ger et rĂ©actif que ce dernier, Ă lâinstar de Svelte. En effet, SolidJS prĂŽne la ârĂ©activitĂ© fineâ en opĂ©rant les changements directement depuis le DOM, plutĂŽt quâĂ travers un DOM virtuel.
De ce fait (et dâaprĂšs les tests de performance de la communautĂ© open-source), cette nouvelle monture serait Ă la fois plus rapide que React, Vue, Preact (qui possĂšde pourtant dâun DOM virtuel plus lĂ©ger que React), ainsi que Svelte, et arriverait en tĂȘte des scores !
Débuter avec SolidJS
DĂ©buter avec SolidJS est un jeu dâenfant (je recommande malgrĂ© tout dâavoir les bases de JavaScript, ainsi que la maitrise de certaines notions de framework orientĂ© composants, pour bien comprendre ce quâest la rĂ©activitĂ©âŠ). Il suffit de faire appel Ă la librairie de Rich Harris (degit
), afin d'Ă©chafauder le projet. Ainsi, l'environnement JavaScript sera prĂ©-configurĂ©e pour fonctionner Ă partir dâun bundler, non pas Webpack cette fois-ci, mais bien Vite !
PropulsĂ© majoritairement par la communautĂ© de Vue, Vite est un outil JavaScript dâun nouveau genre, vous permettant de dĂ©marrer un nouveau projet Web extrĂȘmement rapidement, tout en proposant un environnement moderne. InspirĂ© de RollupJS (mais aussi ESBuild), Vite se dote de nombreuses fonctionnalitĂ©s, Ă savoir :
- La gestion des dépendances NPM
- La pre-compilation des sources (lui permettant de gagner énormément de temps au démarrage)
- Le remplacement des modules Ă chaud (HMR)
- Le support natif de TypeScript
- La transpilation de JSX à la volée
- Le support des modules CSS
- La gestion dynamique des imports
- Lâoptimisation de la compilation, etcâŠ
NB : LâĂ©cosystĂšme de Vite apporte Ă©galement Vitest pour les tests unitaires, en alternative Ă Jest.
SolidJS offre une large palette de templates permettant dâinitialiser un nouveau projet, avec le choix du langage : soit JavaScript, soit TypeScript ; lâintĂ©gration dâune librairie UI prĂȘte Ă lâemploi (notamment lâexcellentissime TailwindCSS), mais aussi lâimplĂ©mentation dâun moteur de tests unitaires : Jest / Vitest (au choix).
Ci-dessus, voici Ă quoi peut ressembler un premier composant de compteur simple avec SolidJS, et son opposĂ© cĂŽtĂ© React. On sâaperçoit trĂšs vite des similitudes qui existent entre ces deux librairies. Et pourtant, SolidJS se veut plus explicite et simple !
En effet, plutĂŽt que dâavoir un hook useEffect
qui permet à la fois de gérer le montage et le démontage du composant (au travers une fonction de cleanup
), SolidJS expose ses actions avec les fonctions de son cycle de vie : onMount
et onCleanup
.
De mĂȘme, lâAPI createSignal
est relativement identique au hook useState
de React dans son fonctionnement, puisque le flux de donnĂ©es est unidirectionnel. Dâun cĂŽtĂ© lâaccesseur (immutable), et de lâautre le "setter". Pourtant, il existe une diffĂ©rence non nĂ©gligeable avec SolidJS ! La notion de "rĂ©activitĂ© fine" pars du principe que les composants ne se rendent quâune fois, et que les fonctions associĂ©es aux Signals sont exĂ©cutĂ©es dĂšs lors que ces derniers sont mis Ă jour. Les changements seront ensuite impactĂ©s directement dans le DOM. Puisque lâaccĂšs Ă la valeur dâun Signal ne se fait quâen lâappelant (prĂ©sence des parenthĂšses), je considĂšre davantage lâaccesseur comme un "getter", plutĂŽt quâune constante... Les Signals sont le concept clĂ© de SolidJS !
Dans lâensemble SolidJS est vraiment simple Ă prendre en main, lâapprentissage de son API est Ă©galement facilitĂ© du fait dâune documentation enrichie et dâune partie âplaygroundâ permettant de comprendre chaque aspect de cette librairie, et de monter en compĂ©tence petit Ă petit.
Bien quâĂ©lĂ©mentaire, SolidJS est un framework complet, puisquâil propose aussi une solution de routage (npm install solid-app-router
), une fonctionnalité de "code splitting" grùce au chargement asynchrone des composants (rendu possible grùce au bundler), ou encore la possibilité de rendre son application cÎté serveur (SSR). Ainsi SolidJS, se classe parmi les grands (React, Vue, etc...) en tant que librairie Web pour créer des interfaces utilisateurs.
Construire des interfaces utilisateurs
Assez de thĂ©orie, passons maintenant Ă la pratique ! Et quoi de mieux que la mise en pratique que dâĂ©voluer dans un cas concret⊠Pour cela, je vous propose de crĂ©er un nouveau projet, pour gĂ©rer lâalimentation et lâaffichage dâune modale, afin dâaborder les notions de rĂ©activitĂ© de SolidJS. Câest parti !
npx degit solidjs/templates/js-vitest my-awesome-app
cd my-awesome-app
npm install
Et voilà ! Vous devriez voir apparaitre un nouveau répertoire (my-awesome-app
dans mon cas), léger en termes de dépendances, mais déjà pré-configuré pour fonctionner /vit/
!
NB : Dans le cadre de mes travaux, jâai aussi ajoutĂ© le support de TailwindCSS Ă lâinitialisation du projet (npx degit solidjs/templates/js-tailwindcss
), puis fusionné les deux configurations de Vite manuellement.
La modale reprĂ©sente un composant stateless qui sâĂ©tend visuellement sur tout lâĂ©cran (si on considĂšre lâarriĂšre-plan assombri et le centrage de lâĂ©lĂ©ment principal), et qui nâattend que des valeurs via les props
pour prendre vie. Ceci facilite aussi les tests unitaires avec Vitest (et Testing Library).
LâAPI de SolidJS peut rendre la syntaxe un peu verbeuse Ă premiĂšre âVueâ đ, mais ses composants sont indispensables afin dâopĂ©rer un changement dans le DOM, en lâabsence de DOM virtuel. Ainsi sa simplicitĂ© repose sur une combinaison astucieuse de Signals (immutables) et de composants (<Show>
, <Switch>
, <For>
, etc...) pour rendre le DOM réactif aux endroits souhaités !
NB : Ă noter quâici, on utilise lâAPI mergeProps
afin d'imposer des valeurs par défaut aux props
. LĂ encore, il est important d'utiliser cette fonction pour conserver la rĂ©activitĂ©, plutĂŽt que d'initialiser ces mĂȘmes valeurs directement depuis la signature du composant (comme avec React).
Pour ce qui est de lâusage, le dĂ©clenchement de lâaffichage de la modale (ainsi que son alimentation) sâopĂšre via des Signals, depuis le composant parent. Ci-dessus, je me suis amusĂ© Ă changer lâaspect de la modale en fonction du temps, pour observer la rĂ©activitĂ©. Ă nouveau, cela peut sembler verbeux, et pourtant câest simple et efficace !
Ce mode de fonctionnement, nâest parfois pas suffisant, notamment lors du dĂ©veloppement dâune application Ă lâĂ©chelle, ou bien lorsquâon utilise un systĂšme de routage (npm install solid-app-router
), pour sĂ©parer les pages de son application. La gestion de la modale, serait possible en utilisant une logique de "props drilling" (parent vers enfant, enfant vers sous-enfant, etc...), mais on tomberait vite dans une complexitĂ© liĂ©e Ă lâimbrication de composants, ainsi quâĂ leur maintenance... Pas de problĂšme ! Pour ce qui est des modales, il y a le composant <Portal>
; pour tout le reste, il y a lâAPI "Context" !
LâAPI Context
NB : Dans un prĂ©cĂ©dent article, jâexplique comment il est possible de mettre en oeuvre un Redux âmaisonâ, avec lâAPI Context de React, ici la logique est la mĂȘmeâŠ
Le State Management (via lâAPI Context), est un paradigme de programmation rĂ©active idĂ©al pour les dĂ©veloppements volumineux, permettant dâĂ©viter le problĂšme de âprops drillingâ, mais aussi de prĂ©sence de donnĂ©es en double / triple⊠De cette maniĂšre, on dit que le "store" est unique source de vĂ©ritĂ© de lâapplication.
NB : Pour en savoir plus sur ce sujet, nâhĂ©sitez pas Ă consulter le code source de mon projet sur Gitlab (et Vercel).
Vous reprendrez bien un supplément de tests unitaires ?
LâĂ©cosystĂšme propulsĂ© par SolidJS, prĂŽne des technologies modernes telles que PNPM, Vite, Vitest mais aussi Testing Library. En sâappuyant sur lâimplĂ©mentation de Preact, lâĂ©quipe de SolidJS apporte le framework de tests unitaires orientĂ©s composants, qui a dĂ©jĂ fait ses preuves avec React, Vue, Angular, Cypress, etcâŠ
Simplicité + Réactivité === Performance
Jâai vraiment apprĂ©ciĂ© jouer avec ce nouveau framework (comme souvent avec les technologies JavaScript). On y retrouve beaucoup de notions de ses homologues, ainsi que des nouvelles telles que les Signals, ou encore la fonction createResource
(trĂšs pratique pour le requĂȘtage dâAPI). Je nâai pas eu de grandes difficultĂ©s Ă crĂ©er mon application de contrĂŽle de noeud (de A Ă Z), puisque ce dernier offre une grande flexibilitĂ© dans lâorganisation du projet. LâexpĂ©rience dĂ©veloppeur est donc optimale !
NB : Ă lâinverse de React (ou Vue), SolidJS compile son code dĂšs la phase de dĂ©veloppement (comme Svelte). De cette maniĂšre, il est en capacitĂ© dâopĂ©rer efficacement et rapidement les changements dans le âvraiâ DOM ; un point supplĂ©mentaire en faveur de lâexpĂ©rience dĂ©veloppeur ! đ
Ce premier tour dâhorizon me donne envie dâen savoir plus et de proposer la dĂ©marche dans un cas dâentreprise. Peut-ĂȘtre en remplacement de Preact, ou mĂȘme de React⊠SolidJS ne propose pas que les composants et fonctionnalitĂ©s dĂ©montrĂ©s ci-dessus. Si je devais faire une liste (non exhaustive), cette librairie propose Ă©galement :
- Le rendu dynamique dâune liste dâĂ©lĂ©ments, depuis (non pas
Array.prototype.map
mais) son composant<For>
- Lâencapsulation des appels asynchrones (en tant que ressources), pour une meilleure visibilitĂ© de lâĂ©tat de chargement, ainsi que la prĂ©sence (ou non) dâerreur(s)
- Lâaffichage dâinterfaces en cas de chargement lĂąche (composants ou ressources), via le composant
<Suspense>
- Lâaffichage dâinterfaces en cas dâerreur(s), afin dâĂ©viter le crash de lâapplication
- Le mode de fonctionnement SSR, pour des gains de performance, mais aussi pour un meilleur SEO (ici SolidJS, marche sur les plate-bandes de Nuxt, Next ou encore SvelteKit)
- Ou encore, la rĂ©conciliation de âstoreâ, permettant de faire cohabiter Redux dans une application Ă lâĂ©chelle
Du fait de ses concepts simples Ă apprĂ©hender, et malgrĂ© lâabsence de DOM virtuel, SolidJS a su prouver sa force et sa stabilitĂ© (en 5 ans de dĂ©veloppement), en poussant la rĂ©activitĂ© en sa forme la plus pure : les Signals ! Tout comme Svelte, ce framework tournĂ© vers lâavenir a de beaux jours devant lui. Coup de â€ïž de lâannĂ©e !