David Hockley

Runes: La Réponse Au Problème magique de Svelte

Intro

Svelte est un excellent framework. Il utilise son compilateur pour augmenter la syntaxe JS classique avec de la réactivité et de l'état.

Mais cette magie du compilateur est aussi un problème. Pourquoi ? Nous y reviendrons dans une seconde.

Parce que pour résoudre ce problème, l'équipe de Svelte renforce la dimension magique, sans en avoir honte, avec une nouvelle fonctionnalité qui arrivera dans Svelte 5 : les Runes.

Les Runes utilisent la syntaxe de fonctions pour fournir une magie réactive plus expressive.

Que sont les Runes ? Est-ce qu'elles rendent Svelte plus magique ? Ou bien Svelte devient-il moins magique ? Les Runes rendent-elles Svelte plus proche de... eh bien, du cadre qui ne doit pas être nommé ?

Qu'est-ce que cela signifie pour l'avenir de Svelte ?

Nous allons nous pencher sur toutes ces questions et sur bien d'autres encore. Pour comprendre tout cela, nous devons d'abord comprendre le problème que les Runes tentent de résoudre.

Quel est le problème magique de Svelte ?

Svelte utilise aujourd'hui let, =, le mot-clé export et le label $: pour gérer l'état. Mais cela pose un problème. Cela crée un raccourci mental (ou "heuristique") où vous vous attendez à ce que cette syntaxe fonctionne d'une certaine manière.

Tant que vous restez dans le contexte où la syntaxe fonctionne, tout va bien. Mais ce contexte est limité. Cette syntaxe ne fonctionne pas de la même manière dans les fichiers javascript, ni dans des fonctions.

Lorsque vous sortez de ce contexte, le raccourci mental échoue, ce qui peut être source de confusion.

Ainsi (par exemple), si nous enveloppons le let réactif d'un composant Svelte dans une fonction, cela ne fonctionne plus comme prévu.

Quelle est donc la solution ?

Tout d'abord, regardons comment Svelte implémente la réactivité.

La Réactivité de Svelte

Une bonne façon de comprendre cela est de le comparer à la façon dont React fonctionne.

React conserve une copie de l'état de l'arbre des composants en mémoire. C'est ce qu'on appelle le DOM virtuel. Lorsque l'état change, React compare les nœuds et re-rend les nœuds affectés par le changement. C'est simple à comprendre, mais c'est pas très subtil.

Svelte utilise le compilateur pour analyser le code. Il détecte les variables qui expriment un état. Il détermine le graphe de dépendance qui les relie. (Au besoin voici une explication plus approfondie du fonctionnement de Svelte.)

Lorsqu'une variable change quelque part, l'application sait exactement quelle partie de l'interface doit être modifiée. C'est ce que nous entendons par réactivité fine : le compilateur relie les différents éléments qui changent.

Cette approche pose un problème. Vous ne pouvez exprimer la réactivité que si vous envoyez les bons signaux au compilateur.

Par exemple, dans le code suivant, le compilateur ne peut voir la dépendance sur la width que lorsqu'il analyse le code au niveau de l'étiquette $:, et ne voit que la width.

La surcharge de let et = est limitée au niveau supérieur des composants Svelte.

Avec un état complexe, la magie implicite du compilateur devient une contrainte. Si vous avez besoin d'encapsuler la logique de votre état dans un fichier JavaScript, vous ne pouvez pas. Si vous voulez la placer dans une fonction, vous ne pouvez pas.

Pour résoudre ce problème, Svelte annonce les Runes, qui feront partie de Svelte 5 (lorsqu'il sortira). Que sont les Runes ?

La solution magique de Svelte : Runes

Le billet de blog indique : "Les runes sont des symboles qui influencent le compilateur Svelte pour obtenir le même effet que les surcharges syntaxiques précédentes.” Les runes sont un moyen de se brancher explicitement sur la magie du compilateur. Les runes vous permettent d'invoquer la magie du compilateur de Svelte.

Et je pense que c'est pour cela qu'elles sont appelées runes. Elles me rappellent les macros de compilation dans des langages comme C++.

Sous le capot, les Runes informent le compilateur de mettre en place une réactivité en utilisant des "signaux".

Que sont les signaux ? Et comment fonctionnent-ils ? Il s'agit d'un paradigme utilisé dans un grand nombre de frameworks frontaux, à l'exception notable de React.

Comme je l'ai mentionné, le compilateur crée un graphe de dépendance entre les variables d'état. Les signaux sont une version de ce graphe de dépendance qui fonctionne à l’exécution. Les signaux connectent l'état et l'interface non seulement lorsque le code est compilé, mais aussi lorsqu'il est exécuté.

Commençons par un exemple simple. Pour définir l'état, nous utilisons la rune $state. Ainsi, au lieu de

let count = 0 ;

nous pouvons maintenant écrire

let count = $state(0) ;

Cela rend beaucoup explicite le fait que la variable contient un état.

Cela indique explicitement au compilateur : C'est volontairement une variable qui contient un état.

L'utilisation d'un symbole explicite (au lieu de surcharger la syntaxe JS) nous permet d'utiliser ce code plus largement. Au sein d'une bibliothèque partagée, par exemple, et pas seulement au niveau supérieur du composant.

De la même manière, et pour la même raison, la syntaxe export let est utilisée pour déclarer des props (par exemple, comme ceci) :

export let width = 0;

... sera remplacée par la syntaxe $props() comme ceci :

const {width = 0} = $props() ;

Maintenant, comme nous l'avons vu dans l'exemple de la multiplication par la hauteur, la réactivité et le suivi des dépendances de Svelte ne sont actuellement disponibles qu'au moment de la compilation :

const multiplyByHeight = (width) => width * height ;
$ : area = multiplyByHeight(width) ;

Comme mentionné ci-dessus, le compilateur ne voit ici qu'une dépendance sur width, pas sur height.

Les runes permettent une réactivité en temps réel où les dépendances sont déterminées lorsque l'expression est évaluée. Pour déclarer les dépendances, nous utilisons la rune $derived. Ici, area sera mis à jour dynamiquement lorsque la variable height changera :

const multiply = (width) => return width * height ;
const area = $derived(multiply(width)) ;

Et pour exécuter du code en cas de changement, nous utilisons la rune $effect.

$effect(() => {
 console.log(area) ;
}) ;

Qu'est-ce que tout cela signifie en pratique pour Svelte ? S'agit-il d'un pas en arrière ou d'un pas en avant ?

Qu’est-ce que ça signifie pour Svelte ?

Eh bien... nous verrons en pratique. Pour l'instant, nous n'avons qu'un sandbox pour tester. La nouvelle syntaxe rend la plupart des syntaxes classiques de Svelte obsolètes. La syntaxe $: et les surcharges de let et export ne seront plus utiles et seront progressivement supprimés.

J'aimais bien l'idée d'utiliser le compilateur pour définir l'état implicitement.

Mais j'avais peur de la confusion que cela pourrait causer. Il semble que l'équipe de Svelte soit arrivée à la même conclusion. Bien qu'en regardant le discord de Svelte, tout le monde n'est pas d'accord avec ce changement.

Mais je pense que c'est un pas dans la bonne direction. C'est un signe de maturité du framework. Svelte fais un pas vers une utilisation plus répandue. Cette modification ouvre la porte à des applications plus complexes. Mais je ne suis pas sûr que la communauté Svelte approuve ce changement.

Mon point de vue : En vous permettant de déclencher la magie de manière explicite, Svelte vous donne de plus grands pouvoirs (et bien sûr de grandes responsabilités). Je suis fan de ce changement et j’ai hâte de pouvoir l’utiliser “en vrai”.

Social
Made by kodaps · All rights reserved.
© 2023