Cette nouvelle syntaxe veut remplacer le JSX

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00D'abord on a eu le JSX, puis le TSX, mais on est bloqué avec ça depuis des années.
00:00:04Est-ce qu'on ne peut pas les améliorer ? Eh bien, peut-être avec TSRX.
00:00:08C'est un peu la même chose, mais c'est différent.
00:00:10On n'a pas de fonction, on a un composant, on a des chaînes pour nos textes,
00:00:14il y a une condition "if" normale ici, et il n'y a pas non plus d'instruction "return".
00:00:17Alors, qu'est-ce que c'est, pourquoi, et devriez-vous l'utiliser ? Découvrons-le.
00:00:21[Musique]
00:00:26Il se peut que certains d'entre vous aient déjà vu ce genre de code,
00:00:29et c'est parce que cela vous est proposé par le créateur de Ripple.
00:00:31C'est un nouveau framework front-end que Rich a présenté sur cette chaîne il y a six mois,
00:00:35alors abonnez-vous pour rester à jour sur ces sujets.
00:00:38Ce qu'ils ont fait, c'est extraire la syntaxe utilisée dans Ripple,
00:00:41et ils l'ont rendue compatible avec React, Preact, Solid, Vue, et Ripple bien sûr,
00:00:45et beaucoup de gens étaient plutôt enthousiastes.
00:00:47TSRX se décrit comme un moyen d'écrire des composants UI lisibles et colocalisés,
00:00:52où la structure, le style et le flux de contrôle vivent ensemble,
00:00:55et le résultat reste entièrement rétrocompatible avec TypeScript.
00:00:58Mais à moins d'avoir déjà utilisé Ripple, vous êtes probablement encore un peu confus,
00:01:01alors passons en revue ses fonctionnalités.
00:01:03Pour commencer, on l'utilise avec des fichiers .tsrx, ce qui implique une étape de compilation,
00:01:07mais c'est super facile à configurer avec un plugin Vite,
00:01:10et il y a aussi d'autres options pour d'autres frameworks et environnements d'exécution.
00:01:13Pour les composants eux-mêmes, au lieu d'écrire "function" ici, on écrit "component",
00:01:17et c'est surtout un mot-clé pour le compilateur lui-même,
00:01:20mais cela indique aussi clairement que cela va contenir de la logique de rendu.
00:01:24Je considérerais cela comme une petite amélioration du confort de travail.
00:01:27Une chose à noter cependant, c'est que nous n'avons pas d'instruction "return" ici,
00:01:30et c'est parce que TSRX utilise un JSX basé sur des instructions (statement-based JSX),
00:01:33vous n'avez donc pas besoin de renvoyer un arbre de composants,
00:01:35vous écrivez juste votre balisage là où vous voulez qu'il s'affiche.
00:01:37Cela signifie qu'on peut ajouter une autre balise de paragraphe au-dessus de cette carte tout en haut du composant,
00:01:42et elle s'affichera exactement là où elle est écrite.
00:01:44On peut toujours utiliser un "return" dans un composant, mais il doit être vide,
00:01:47et il sert uniquement à un retour anticipé, pour ignorer l'interface et la logique qui suivent.
00:01:51Cela m'a aidé de penser aux composants TSRX comme étant très linéaires,
00:01:54l'ordre d'écriture dans le code source correspond donc à l'ordre de rendu,
00:01:57en lisant simplement de haut en bas,
00:01:59mais je vois aussi que cela pourrait rendre plus difficile de voir rapidement ce qu'un composant affiche,
00:02:03alors que dans React, on cherche directement l'instruction "return".
00:02:06Un autre avantage du JSX basé sur des instructions est qu'on peut utiliser du JavaScript beaucoup plus standard.
00:02:10Par exemple, le rendu conditionnel est super simple.
00:02:13C'est juste un bloc "if" avec un "else-if" et un "else" si besoin.
00:02:17Dans les conditions, il suffit de placer notre JSX sous forme d'instruction.
00:02:20Cette même structure dans React se transforme souvent en ternaires imbriquées,
00:02:23car en JSX, chaque branche doit être une expression,
00:02:26je trouve donc que la version TSRX est parfois plus facile à lire,
00:02:29surtout quand on a une condition plus complexe,
00:02:31mais d'un autre côté, je vois aussi que cela peut être plus verbeux,
00:02:35surtout quand on a juste besoin d'une condition simple.
00:02:37C'est la même chose pour les instructions "switch" également.
00:02:39Vous pouvez utiliser un "switch" JavaScript normal avec vos cas
00:02:41et le JSX que vous voulez afficher pour chacun d'eux.
00:02:44C'est un peu plus simple que la façon de gérer ça dans React,
00:02:47où il faut une fonction pour utiliser le même modèle,
00:02:49TSRX est donc un peu plus propre ici,
00:02:51mais un domaine que j'aime personnellement moins dans TSRX est le rendu de listes.
00:02:55Ici, on abandonne le ".map" et on utilise plutôt une boucle "for-of",
00:02:58et TSRX a en fait étendu cette boucle pour qu'on puisse récupérer l'index
00:03:01ainsi qu'une identité stable avec la clé.
00:03:03Ensuite, quand on veut sauter un élément, on peut simplement utiliser "continue",
00:03:06donc à nouveau, c'est un peu plus proche du flux JavaScript natif,
00:03:08mais comme je l'ai dit, pour ma part, j'ai l'habitude d'utiliser ".map", ".filter", etc.,
00:03:12donc je vais probablement m'en tenir à ça,
00:03:14et il est aussi important de noter qu'on ne peut pas utiliser d'autres types de boucles
00:03:17comme "for", "for-in", "while" et "do-while".
00:03:19Cela ne fonctionne qu'avec les boucles "for-of".
00:03:21Pour continuer sur la lancée du JavaScript standard,
00:03:23la façon de faire des limites d'erreur (error boundaries) dans TSRX se fait avec un simple bloc "try-catch".
00:03:27Rien de compliqué et c'est assez explicite.
00:03:30On peut également utiliser ce même bloc "try-catch" si on a besoin de limites asynchrones,
00:03:33il suffit d'ajouter un bloc "pending"
00:03:35et d'y écrire votre composant de chargement.
00:03:38Le compilateur s'occupe de prendre ce code
00:03:40et de le résoudre selon le framework que vous utilisez,
00:03:42donc dans React, Preact et Solid, cela utilise en fait "lazy",
00:03:45et dans Ripple, c'est l'équivalent de Ripple.
00:03:47En parlant de React spécifiquement,
00:03:48les fonctionnalités que nous avons vues jusqu'à présent
00:03:50semblent nous permettre d'enfreindre l'une des règles clés de React,
00:03:53la règle des hooks.
00:03:54On peut désormais les placer après des conditions et des retours anticipés,
00:03:57et même à l'intérieur de boucles.
00:03:58Ils fonctionneront tous normalement.
00:04:00Cela nous permet de mieux colocaliser notre code là où il est vraiment nécessaire,
00:04:03et le résultat final n'enfreint même pas les règles.
00:04:06Le compilateur remonte simplement discrètement chaque hook en haut de la fonction générée,
00:04:09React les voit donc toujours dans un ordre stable,
00:04:11mais vous pouvez les écrire là où ils ont le plus de sens.
00:04:14Pour moi, en tant que personne qui utilise React depuis des années,
00:04:16c'est l'une des choses avec lesquelles j'ai du mal à me familiariser,
00:04:18et c'est aussi une fonctionnalité où l'on demande au compilateur
00:04:20de faire beaucoup de magie en coulisses,
00:04:22spécifiquement autour d'un framework,
00:04:24et je pense que si je devais déboguer ça,
00:04:26je m'y perdrais un peu pour savoir quel code est où.
00:04:28Ensuite, nous avons la portée lexicale (lexical scoping),
00:04:30chaque élément imbriqué crée donc sa propre portée,
00:04:32on peut donc déclarer une constante "label" dans trois blocs "div" différents ici,
00:04:36et elles n'entrent pas en conflit.
00:04:37Il y en a même une en haut de la fonction ici que rien ne lit,
00:04:40et là encore, il n'y a pas de conflit.
00:04:41C'est la même chose pour chaque instruction "if", "for", "switch" ou "try".
00:04:44Chacune a ses propres portées,
00:04:46ainsi les variables qu'on déclare, les fonctions qu'on exécute,
00:04:48et les valeurs qu'on en tire ne débordent pas sur les autres portées.
00:04:51C'est une autre de ces fonctionnalités axées sur la colocalisation du code,
00:04:54et à nouveau, cela permet de lire nos composants de façon linéaire, de haut en bas.
00:04:57Pour changer un peu du JavaScript, parlons du style.
00:05:00Dans TSRX, nous avons des styles à portée limitée (scoped styles),
00:05:02on peut donc juste placer un bloc "style" dans notre composant,
00:05:04et le CSS qu'on y écrit est limité uniquement à ce composant,
00:05:08avec un hachage unique attaché au nom de la classe lors de la compilation.
00:05:11Ce composant de carte a donc une classe "card",
00:05:13et remarquez ici, il essaie aussi d'utiliser cette classe "card",
00:05:16mais il ne reçoit aucun style de carte,
00:05:17car il n'a pas de bloc de style propre.
00:05:19Il ne reçoit pas le style de son parent,
00:05:21parce qu'il n'a pas ce hachage unique.
00:05:22Si vous voulez partager des styles entre les composants cependant,
00:05:24TSRX a un mot-clé "style",
00:05:26le parent transmet donc le nom du style avec ce mot-clé
00:05:29à un composant qui accepte "className" comme propriété,
00:05:31et il s'assurera que ce hachage unique généré l'accompagne.
00:05:35On remarque maintenant qu'il a le même style que le parent.
00:05:37Techniquement, on peut aussi utiliser un sélecteur global autour de nos styles
00:05:40pour échapper à la portée limitée et appliquer ces styles globalement,
00:05:42mais je pense que ça va devenir un peu désordonné,
00:05:44et que l'on perdra le fil de la provenance de nos styles.
00:05:46Personnellement, je ne jure que par Tailwind,
00:05:48donc je n'utiliserai probablement pas beaucoup cette fonctionnalité,
00:05:50et je vais m'en tenir à Tailwind,
00:05:51mais c'est quand même plutôt sympa.
00:05:53Ensuite, une fonctionnalité pour ceux d'entre vous qui ont été attentifs.
00:05:56Dans les blocs de code que j'ai montrés,
00:05:57il y avait une petite différence dans la façon dont le texte est géré dans ces instructions.
00:06:01Le texte brut à l'intérieur d'un élément doit être entouré de guillemets doubles.
00:06:04On ne peut pas simplement l'écrire comme on le fait en JSX.
00:06:07On peut toujours utiliser des valeurs dynamiques cependant,
00:06:08comme dans une ligne comme celle-ci,
00:06:10qui se trouve entre deux chaînes de caractères entre guillemets doubles,
00:06:12et TSRX va simplement concaténer cela en une seule chaîne lors de la compilation.
00:06:16Une autre option que vous avez est de simplement utiliser un littéral de gabarit.
00:06:19On obtient le même résultat.
00:06:20Pour moi, cela a été l'un des petits inconvénients de l'utilisation de TSRX
00:06:23parce que j'ai l'habitude de ne pas utiliser de guillemets pour le texte.
00:06:26Une autre fonctionnalité textuelle cependant,
00:06:27est que TSRX peut réellement gérer des chaînes contenant du balisage HTML réel,
00:06:31et on a deux façons de faire le rendu.
00:06:33La première est simplement d'utiliser le mot-clé "text",
00:06:35qui va afficher le texte échappé,
00:06:38afin que vous puissiez voir la chaîne HTML littérale,
00:06:40et c'est également protégé contre le cross-site scripting.
00:06:42C'est donc utile lorsqu'on veut s'assurer que quelque chose sera une chaîne,
00:06:45et que la source de cette chaîne est un peu ambiguë,
00:06:48on ne connaît donc pas forcément son type en écrivant ce code.
00:06:51La deuxième option est pour si l'on veut afficher la chaîne sous forme de HTML,
00:06:54on peut simplement utiliser le mot-clé "HTML",
00:06:56et cela l'analyse comme du vrai HTML,
00:06:58mais cette fonctionnalité ne fonctionne que dans Ripple, Vue en supportant une version plus restreinte.
00:07:02Une autre fonctionnalité non liée à React,
00:07:03mais qui pourrait intéresser ceux d'entre vous qui utilisent Ripple,
00:07:06Vue ou Solid, est la déstructuration paresseuse (lazy destructuring).
00:07:08Si vous déstructurez vos propriétés normalement dans ces frameworks,
00:07:10vous figez chaque valeur au moment de l'appel,
00:07:12et cela brise la réactivité basée sur l'accès.
00:07:14Donc dans TSRX, vous pouvez simplement ajouter une esperluette avant les propriétés,
00:07:18et bien que cela ressemble à de la déstructuration,
00:07:20chaque liaison est en fait recompilée en une recherche de propriété là où elle est utilisée.
00:07:23Ainsi, l'environnement d'exécution voit chaque accès individuellement,
00:07:25les mises à jour des signaux déclenchent donc toujours des nouveaux rendus,
00:07:28ce qui signifie que vous conservez l'ergonomie de la déstructuration,
00:07:30et le framework conserve sa réactivité.
00:07:32La dernière fonctionnalité que je vais montrer est une petite amélioration simple du confort d'écriture.
00:07:35Avez-vous déjà eu une propriété où la valeur que vous lui passez a le même nom que cette propriété,
00:07:40le plus souvent dans une fonction comme "onchange" ?
00:07:42Eh bien, avec TSRX, vous pouvez simplement l'écrire en raccourci,
00:07:45similaire à ce que l'on peut faire avec les objets JavaScript.
00:07:47C'est propre et simple.
00:07:49Dans l'ensemble, TSRX semble vouloir réintégrer le flux JavaScript normal dans le JSX
00:07:53tout en ajoutant quelques améliorations de confort,
00:07:55et j'aime beaucoup de ses éléments.
00:07:57Je pense sincèrement que son principal défaut est d'être trop de niche et d'arriver trop tard
00:08:01alors que l'IA écrit la majeure partie de notre code,
00:08:03et le code que l'IA sait bien écrire semble être le JSX et React.
00:08:07Ceci étant dit, j'ai soumis quelques démos à Claude en utilisant TSRX,
00:08:10et il a réussi à bien l'écrire simplement en se basant sur le fichier "llms.txt" du site,
00:08:14mais je pense quand même m'en tenir à React classique pour ma part.
00:08:17L'autre inconvénient, c'est qu'on a l'impression, surtout pour React,
00:08:19que cela rajoute encore de la magie de compilateur par-dessus,
00:08:21et cela casse aussi des habitudes que j'ai mis des années à acquérir,
00:08:24donc ce n'est pas pour moi personnellement, mais cela ne veut pas dire que c'est mauvais.
00:08:27Je pense que les personnes venant de Svelte pourraient beaucoup aimer cela,
00:08:30et si vous utilisez déjà Ripple, vous adorez probablement déjà ça.
00:08:33Dites-moi dans les commentaires ci-dessous si c'est le cas,
00:08:35pendant que vous y êtes, abonnez-vous, et comme toujours, à la prochaine.
00:08:40[Musique]

Key Takeaway

TSRX réintègre les structures de contrôle JavaScript natives comme les blocs "if", "switch" et "try-catch" directement au cœur du balisage grâce à un compilateur qui résout ces structures pour React, Preact, Solid, Vue et Ripple.

Highlights

  • TSRX introduit un JSX basé sur des instructions (statement-based JSX) qui supprime le besoin d'utiliser l'instruction "return" pour afficher du balisage.

  • Cette syntaxe permet de contourner la règle stricte des hooks de React en autorisant leur déclaration sécurisée à l'interieur de boucles, de conditions et après des retours anticipés grâce à une remontée automatique (hoisting) au moment de la compilation.

  • L'utilisation de TSRX impose d'entourer tout texte brut d'un élément par des guillemets doubles, se démarquant du JSX classique.

  • Pour préserver la réactivité dans les frameworks basés sur les signaux comme Solid ou Ripple, le préfixe d'esperluette devant les variables déstructurées active la déstructuration paresseuse.

  • La gestion des erreurs et de l'asynchronisme s'effectue via des blocs standards "try-catch" et des sections "pending", que le compilateur traduit selon les spécificités de chaque framework.

Timeline

Origine et définition du TSRX

  • TSRX provient de l'extraction de la syntaxe utilisée dans le framework front-end Ripple.
  • Ce format est conçu pour être entièrement rétrocompatible avec TypeScript.

Issu des travaux du créateur de Ripple, TSRX se présente comme une alternative au JSX et au TSX traditionnels. Son objectif principal est de permettre l'unification de la structure, du style et du flux de contrôle au sein de composants UI lisibles. Il offre une compatibilité multi-framework incluant React, Preact, Solid, Vue et Ripple.

La structure de rendu sans instruction "return"

  • Le mot-clé "component" remplace le mot-clé standard "function" pour signaler la logique de rendu au compilateur.
  • L'absence d'instruction "return" oblige à adopter un rendu linéaire où le balisage s'affiche à l'endroit exact où il est écrit.

Le flux d'exécution s'appuie sur des fichiers .tsrx traités lors de la compilation par un plugin Vite. Dans ce paradigme basé sur des instructions, le développeur n'a pas besoin de renvoyer un arbre de composants structuré. L'utilisation d'un "return" vide reste possible uniquement pour stopper précocement le rendu et ignorer le reste du code.

Réintégration des structures de contrôle JavaScript standard

  • Les blocs conditionnels "if", "else-if", "else" et "switch" remplacent les expressions ternaires imbriquées du JSX.
  • Le rendu de listes abandonne la méthode ".map" au profit de la boucle native "for-of" étendue par le compilateur.

L'utilisation de structures de contrôle impératives simplifie l'enchaînement logique et améliore la lisibilité face aux expressions déclaratives complexes de React. La boucle "for-of" intègre la gestion de l'index et des clés d'identification stables, tout en autorisant l'usage de l'instruction "continue". Les autres structures de boucle comme "for", "while" ou "do-while" ne reçoivent aucun support du compilateur.

Gestion des erreurs, de l'asynchronisme et résolution des règles des hooks

  • Les limites d'erreurs s'expriment nativement à l'aide de blocs standard "try-catch" combinés à une section "pending" pour l'asynchronisme.
  • Le compilateur de TSRX contourne la règle des hooks de React en les déplaçant en haut de la fonction finale générée.

La gestion des états de chargement asynchrones utilise les API de lazy loading du framework cible grâce à la compilation de la section "pending". Le développeur peut déclarer des hooks n'importe où dans son code, y compris dans des boucles ou des blocs conditionnels, car le compilateur assure la stabilité de l'ordre d'appel requise par React en arrière-plan.

Portée lexicale, isolation des styles et gestion du texte

  • Chaque bloc de code définit sa propre portée lexicale, évitant les conflits de variables entre composants imbriqués.
  • Les styles s'isolent par composant grâce à des blocs "style" internes dont la classe reçoit un hachage unique à la compilation.
  • Le texte brut au sein du balisage requiert l'usage systématique de guillemets doubles ou de littéraux de gabarit.

Les variables déclarées dans une instruction ne débordent pas sur les portées voisines, ce qui facilite la colocalisation de la logique. Pour l'habillage graphique, le mot-clé "style" permet de propager le hachage CSS parent vers un enfant acceptant la propriété "className". Concernant l'affichage de chaînes contenant du code HTML, les mots-clés "text" (pour l'affichage sécurisé) et "HTML" répondent aux différents cas de figure.

Optimisations spécifiques, limites et adoption technologique

  • L'esperluette placée devant les variables déstructurées convertit l'opération en accès dynamiques pour maintenir la réactivité.
  • Le développement de l'IA limite l'attrait pour de nouvelles syntaxes marginales comme TSRX face au standard JSX mieux maîtrisé par les modèles génératifs.

Dans les environnements à signaux comme Solid, Vue ou Ripple, la déstructuration paresseuse de TSRX prévient la perte de réactivité lors du passage de propriétés. Bien que des modèles comme Claude s'adaptent à TSRX en lisant le fichier "llms.txt" du projet, la complexité additionnelle introduite par le compilateur et la modification des habitudes développement freinent son adoption généralisée.

Community Posts

View all posts