Alexandre CANTIN - Blog personnel

02 août 2021

Svelte : un concurrent de poids face à React-Vue-Angular ?

Svelte bouscule l’éco-système des librairies JavaScript actuellement dominé par le trio React, Vue et Angular. Mais que vaut Svelte comparé à ces “concurrents” et pourquoi parvient-il à séduire de plus en plus de développeurs ? Réponse dans cet article !

Cet article est une transcription de ma présentation de Svelte réalisée le 2 juin 2020 dans le cadre du 10ème SFEIR Talk, dont la vidéo est disponible en fin d’article. J’ai toutefois pris la liberté d’ajouter des explications supplémentaires que je ne pouvais faire à l’oral pour des contraintes de temps; ainsi que les questions post-présentation.

Allons-y !

1- Pourquoi Svelte ?

Nous allons commencer par la question la plus basique qui soit : qu’est-ce que Svelte ?

Svelte est un “compilateur front” qui permet de créer des pages web dynamiques comme nous le faisons déjà avec Angular-React-Vue.js (ou d’autres bibliothèques/frameworks dans le monde très — voire trop — vaste du JavaScript).

Pour désigner Svelte, j’ai utilisé le terme de “compilateur front” et, en effet, contrairement à React-Vue-Angular, qui embarquent des librairies dans le navigateur du client, Svelte est un compilateur et, comme on va le voir, cela va changer pas mal de choses 🙂

1.1 — Pourquoi Svelte est un compilateur ?

Pour répondre à cette question, nous devons tout d’abord nous attarder sur l’origine de Svelte et parler de son créateur Rich Harris (@Rich_Harris).

Rich Harris, le créateur de Svelte

Rich Harris n’est pas un inconnu dans l’univers du JavaScript car on le connaît déjà en tant que créateur de Rollup, une alternative à Webpack.

Aux alentours de 2016, Rich Harris travaille en tant que graphics editors (comprendre “créateur de représentations graphiques” ou Data Visualisation) au New York Times (poste qu’il occupe toujours). Pour la réalisation de ses graphiques animés, Rich Harris utilise à cette époque React et il en est très mécontent car il se heurte souvent aux limites des performances de cette bibliothèque (et de son Virtual DOM), au point qu’il réfléchit à développer sa propre alternative.

Qu’est-ce que Rich Harris reproche à React et surtout à son Virtual DOM ? Pour y répondre, intéressons-nous au fonctionnement du Virtual DOM avec cet exemple simple d’un champ texte dont la valeur est recopiée dans une balise <p>:

import React, { useState } from "react";
function App() {
  const [name, setName] = useState("");
  function updateName(e) {
    setName(e.target.value);
  }
  return (
    <div>
      <h1>Votre nom :</h1>
      <p>{name}</p>
      <input type="text" onInput={updateName} value={name} />
    </div>
  );
}
export default App;

Et dont le résultat serait le suivant :

Si l’on s’intéresse au fonctionnement de React en cas d’écriture dans le champ texte, nous avons la succession d’évènements suivante :

  1. Création d’un nouveau Virtual DOM

  1. Comparaison de l’ancien Virtual DOM avec le nouveau pour déterminer les mises à jour nécessaires

  1. Mise à jour effective du DOM

Comme on peut le voir à l’étape 2, React a procédé à 7 comparaisons alors que 2 d’entre elles n’étaient réellement nécessaires. Ce nombre de comparaisons augmentera d’ailleurs proportionnellement à la taille de notre projet et ralentira notre application au bout d’un certain moment ; nous imposant alors de recourir à des procédés d’optimisation du Virtual DOM comme PureComponent, useCallback, useMemo ou encore shouldComponentUpdate.

Toutefois, nous serons tous d’accord sur le fait que la solution idéale serait de passer directement de la modification du champ texte à la mise à jour du DOM, sans les étapes 1 et 2 :

Figurez-vous que c’est exactement l’objectif visé par Svelte !

Malheureusement, déterminer l’ensemble des conséquences sur le DOM est impossible sans une connaissance accrue de l’application et nécessiterait donc l’intervention au cas par cas du développeur, occasionnant une charge de travail conséquente pour lui… 😔 Ce fut d’ailleurs la grande innovation apportée par React et Angular : automatisez la génération du DOM et limiter le travail du développeur à la modification de l’état de ses variables.

Par conséquent, comment déterminer les actions minimales à effectuer sur le DOM suite à l’action de l’utilisateur sans l’intervention du développeur ? C’est là que le concept de compilateur prend tout son sens.

Ainsi, nous écrirons nos composants dans des fichiers au format .svelte. Le compilateur Svelte va ensuite analyser notre code, le comprendre, déterminer les mises à jour du DOM nécessaires après à la modification d’une variable et générer un fichier .js aux performances optimales :

1.2 — Svelte et la performance

Maintenant si on regarde le même composant écrit en Svelte, nous ne serons que peu dépaysés par rapport à son équivalent React :

<script>
  let name = "";
  function updateName(e) {
    name = e.target.value;
  }
</script>
<h1>Votre nom :</h1>
<p>{name}</p>
<input type="text" on:input="{updateName}" value="{name}" />

Nous retrouvons la même logique :

  • une balise <p> affichant le contenu de la variable name
  • un <input /> qui appelle une fonction updateName suite à une action on:input
  • une fonction updateName qui met à jour la valeur de name avec le contenu de l’input

Et on obtient un résultat similaire :

Toutefois, si on regarde le code source généré par Svelte et notamment le bloc réservé à la mise du DOM :

On remarque que seules deux opérations sur le DOM ont été créées :

  • celle de la mise à jour de la balise <p> (correspondant à une variable t2)
  • celle de la mise à jour de l’attribut value de l’input

De plus, ces deux opérations sont optimales : les valeurs sont mises à jour directement sans actions intermédiaires. On obtient ainsi une performance maximale, impossible en React.

⚠️ N’interprétez pas mal mes paroles : je n’ai pas dit que React est lent. Svelte explore simplement une autre voie lui permettant d’aller plus loin en termes de performance 🙂.

1.3 — Svelte et le sucre syntaxique

Toutefois, soyons honnête, nous nous retrouvons très rarement dans le cas où des performances extrêmes sont requises et choisir Svelte juste pour cela serait peu pertinent. Mais l’approche compilateur apporte un autre avantage qui est le “sucre syntaxique”.

Il s’agit d’un ensemble de raccourcis (pas des centaines rassurez-vous 🙂) qui va vous permettre d’écrire moins de code et bénéficier de tous les avantages que cela implique : moins de code à produire (et donc une amélioration de votre productivité) mais aussi moins de code à maintenir et comprendre.

Par exemple, en partant du code précédent, il est possible de le raccourcir en liant directement la valeur de l’attribut value de l’input avec la variable name via une directive appelée bind.

Il est donc possible de simplifier l’exemple précédent en retirant le on:input={updateName} et la fonction updateName par la même occasion. Nous obtenons ainsi le même résultat mais en plus court :

<script>
  let name = "";
</script>
<h1>Votre nom :</h1>
<p>{name}</p>
<input type="text" **bind:**value="{name}" />

C’est une raison, si ce n’est la raison, qui explique l’appréciation de Svelte auprès des développeurs, car on écrit tout simplement moins de code et on est par conséquent plus productif 🙂

Voici, par ailleurs, la comparaison d’un même composant, réalisant l’addition entre deux nombres puis affichant le résultat, et on ne peut que constater que la version de Svelte est plus légère :

Selon Rich Harris, un composant Svelte est en moyenne 20–30% moins long que son équivalent React.

1.4 — Svelte et le poids du bundle

Dernier point important concernant Svelte est le fait qu’il produise un bundle final avec un poids très faible. En effet, bien que Svelte pèse environ 50 Ko dans son ensemble, seules les fonctions utilisées seront incluses dans le bundle final. Ainsi, contrairement à Angular-React-Vue, nous n’avons pas une librairie pré-inclue qui alourdit notre application avant même que le moindre code n’y soit inclus.

Ainsi, dans l’exemple précédent, nous nous retrouvons avec un poids global de 3,1 Ko (sans compression).

D’ailleurs, si on s’intéresse au package.json du template par défaut d’un projet Svelte, on remarque qu’il n’y a que des paquets servant pour le développement et aucun n’est conservé dans le bundle de production :

Note : le package sirv-cli sert comme serveur de fichier et peut donc être déplacé dans les devDependencies sans souci 🙂 (mais doit toutefois être conservé pour l’environnement de développement).

Comme nous venons de le voir dans cette partie, Svelte se distingue sur trois aspects :

  • Performance accrue
  • Un poids final réduit
  • …le tout avec moins de code

Je pourrais même ajouter un quatrième point qui serait sa simplicité. En effet, une des volontés derrière Svelte, est de se rapprocher le plus possible du HTML et laisser toute la complexité être gérée par le compilateur (optimisation et implémentation des raccourcis syntaxiques).


2 — Tour d’horizon de Svelte

Nous allons dorénavant procéder à un tour d’horizon des fonctionnalités proposées par Svelte, forcément non exhaustif.

2.1 — Anatomie d’un composant

Un composant Svelte se divise en trois parties :

  • <script> pour la partie logique, pour les fonctions et les variables
  • <style> pour la partie design

Tout le reste sera considéré comme la partie template et sera donc destiné à accueillir (majoritairement) du HTML

Ici, la volonté est d’être le plus proche possible d’un fichier HTML tout en gardant que le strict nécessaire. En ajoutant, les balises html, head et body, on pourrait même se croire à l’intérieur d’un fichier HTML :

⚠️ Est-il possible de répartir ces trois zones dans des fichiers distincts ? Non, ce n’est pas possible et ce n’est pas dans la philosophie de Svelte. Bien que la logique de séparation des différents blocs puisse être louable, cela créait un effet de bord. Il devient possible d’inclure un même style ou logique dans des composants différents et entraîne un souci qu’on rencontre très souvent (notamment en CSS) : on ne sait plus si un bloc de code est utilisé ou non au sein de son application. Pour pallier à cela, Svelte impose que les fonctions/style co-habitent avec leur template pour mieux suivre leur zone d’impact.

2.2 — Style

Vous savez faire du CSS ? Bonne nouvelle, vous savez donc déjà designer vos composants Svelte ! En effet, Svelte accepte du CSS natif dans le bloc <style> (un support de Sass ou Less reste toutefois possible) :

Toutefois, le compilateur Svelte va encapsuler ce style avec une classe CSS générée aléatoirement, pour s’assurer que votre style n’affectera pas d’autres composants :

2.3 — Templating

2.3.1 — Conditions

Svelte nous permet bien entendu de modifier le rendu du composant en fonction de conditions exprimées entre accolades :

<script>
  let number = 1;
</script>
{#if number < 0 }
<p>Négatif</p>
{:else if number > 0 }
<p>Positif</p>
{:else}
<p>Égal à 0</p>
{/if}

Ces conditions respectent les mêmes règles d’écriture que celles du JavaScript.

2.3.2 — Boucles

Il est aussi possible d’itérer à travers une collection via {#each myCollection as myValue, index}

À noter que Svelte prévoit aussi une alternative {:else} afin de gérer plus facilement le cas où notre collection serait vide.

<script>
  let numbers = [1, 2];
</script>
{#each numbers as number, index}
<p>{index} => {number}</p>
{:else}
<p>Liste vide</p>
{/each}

Le destructuring est aussi possible directement après le as :

<script>
  let data = [
    { year: "2019", count: "30" },
    { year: "2020", count: "35" },
  ];
</script>
{#each data as { year, count }}
<p>{year} => {count}</p>
{/each}

2.3.3 — Promesses

Svelte met aussi à disposition une syntaxe {#await} faisant varier l’affichage d’un composant en fonction du statut d’une promesse (en cours, terminée ou échouée) :

{#await promise}
<p>...</p>
{:then number}
<p>Le nombre est {number}</p>
{:catch error}
<p class="error">{error.message}</p>
{/await}

2.3 — Gestion des propriétés

Svelte, tout comme Angular-Vue-React, fonctionne via un système de composants et n’innove d’ailleurs guère dans ce domaine. On peut ainsi créer ses propres composants et les inclure dans d’autres composants en leur passant une ou plusieurs propriétés.

Afin d’expliciter si une variable est une propriété, il faut la préfixer par le mot-clé export dans le composant enfant :

<!-- Composant enfant -->
<script>
  export let name = "world";
</script>
<h2>Hello {name}</h2>

Nous obtenons ainsi le résultat suivant :

☝️ Il peut sembler bizarre d’employer le mot export pour indiquer une propriété mais cela me donne l’opportunité de m’attarder sur le fonctionnent du compilateur Svelte. Ce dernier attend du JavaScript natif dans le bloc script (parsé avec la librairie acorn pour les plus curieux). Toutefois, Svelte surcharge JavaScript et par conséquent, la sémantique d’un mot-clé peut dès fois être modifiée, ce qui est exactement le cas ici 🙂

2.4 — Bloc réactif avec $:

Voici un autre exemple de détournement de sémantique par Svelte que sont les blocs réactifs, définis par $:. Ces derniers sont des portions de code qui ne seront exécutées que si les variables qu’ils utilisent sont modifiés :

<script>
  let name = "world";

  let uppercase = "";
  $: uppercase = name.toUpperCase();
</script>
<h1>Hello {name}!</h1>
<input type="text" bind:value="{name}" />
<p>Uppercase : {uppercase}</p>

Dans cet exemple, le code uppercase = name.toUpperCase() ne sera exécuté que si la variable name est modifiée. Autre cas d’usage possible, on peut suivre la modification d’une variable avec $: console.log(maVariable).

Le bloc réactif peut accueillir des cas plus complexes comme des conditions, pour une auto-complétion par exemple : $: if(name.length > 2) fetch(...). De manière générale, vous pouvez considérer les blocs réactifs comme des fonctions avec toutes les possibilités qu’elles offrent 🙂

En React, la fonction useMemo permet d’obtenir ce même comportement. Toutefois, c’est au développeur de déclarer lui-même les variables à surveiller :

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Au sein de Svelte, ces variables sont déduites à la compilation et dispense le développeur d’y réfléchir (et limite les risques d’oubli par la même occasion).

$: est-il une syntaxe valide en JavaScript ? Tout à fait ! Il s’agit de labels statements (servant dans les boucles) mais vu que personne ne les utilise, Svelte les a recyclé pour ses blocs réactifs. Pour en savoir plus : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/label

2.5 — Animations

Pour finir, Svelte nous facilite la création d’animations pour les éléments entrants ou sortants du DOM. Ces effets se réalisent via deux directives in et out dont les noms parlent d’eux-mêmes. Svelte dispose déjà d’animations de base, présentes dans le package svelte/transition mais il est possible de créer les vôtres (qui seront compilés en CSS3 pour obtenir de meilleures performances).

Prenons maintenant un exemple avec celui d’un texte dont la visibilité dépend d’une case à cocher :

<script>
  **import { fade, fly } from 'svelte/transition';**
  let visible = true;
</script>
<label>
  <input type="checkbox" bind:checked="{visible}" />
  visible
</label>
{#if visible} **
<p in:fly="{{ y: 200, duration: 2000 }}" out:fade>** Flies in, fades out</p>
{/if}

Et au niveau du résultat, nous obtenons ainsi :

Selon vos librairies, ces animations peuvent être compliquées à créer mais, encore une fois, Svelte nous simplifie la tâche et nous permet en deux lignes de code — littéralement — de pouvoir créer des contenus animés.

2.6 — Les stores

Nous allons maintenant évoquer la gestion des stores au sein de Svelte.

👉 Un store permet de déporter une partie des données de notre site dans un endroit tiers, la librairie la plus connue étant Redux, utilisée principalement au sein de l’écosystème de React.

2.5.1 — Un premier store

Pour notre premier store, nous prendrons l’exemple très inspiré d’un compteur.

Au sein de Svelte, un store est un objet writable présent dans le package svelte/store qu’il nous faut créer dans un fichier JavaScript (et donc pas un fichier au format .svelte) :

// counter-store.js
import { writable } from "svelte/store";
const counter = writable(0);
export default counter;

Une fois le store de notre compteur créé, avec 0 comme valeur par défaut, il nous faut ensuite :

  • l’importer dans notre composant
  • s’y abonner via la fonction subscribe de notre writable en indiquant la fonction qui sera exécutée lors d’une modification du store (ici, la mise à jour d’une variable interne au composant)
<script>
  // Récupération du store
  import counter from "./counter.js";
  let countValue;
  counter.subscribe((newStoreValue) => (countValue = newStoreValue));
</script>
<h1>Counter : {countValue}</h1>

Malheureusement, cela n’est pas suffisant. En effet, il est aussi nécessaire de se désinscrire du store lors de la disparition du composant afin d’éviter une fuite mémoire. Pour cela, nous récupérons la fonction renvoyée par subscribe que nous appellerons dans la méthode onDestroy, entrant dans le cycle de vie d’un composant Svelte :

<script>
  import { onDestroy } from "svelte";
  import counter from "./counter.js";
  let countValue;
  // Récupération de la fonction de désinscription
  let unsubscribe = counter.subscribe(
    (newStoreValue) => (countValue = newStoreValue)
  );

  // Désinscription du store à la destruction du composant
  onDestroy(() => unsubscribe());
</script>
<h1>Counter : {countValue}</h1>

Et nous obtenons le rendu voulu :

Pour interagir avec le store, deux méthodes sont à notre disposition :

  • update : avec en paramètre une fonction contenant la valeur courante du store
  • set : pour remplacer le contenu du store par une nouvelle valeur

Ainsi, dans notre exemple, nous allons ajouter deux boutons : le premier pour incrémenter la valeur du store et un second pour réinitialiser le store :

<script>
	import { onDestroy } from 'svelte'
	// Récupération du store
	import counter from './counter.js'
	let countValue;
	let unsubscribe = counter.subscribe((newStoreValue) => countValue = newStoreValue)
	onDestroy(() => unsubscribe())
</script>
<h1>Counter : {countValue}</h1>
<!-- Ajout de deux boutons -->
<button on:click={() => counter.update(n => n+1)}>+1</button>
<button on:click={() => counter.set(0)}>Reset</button>

2.5.2 — Encore du sucre syntaxique

Toutefois, nous avons écrit beaucoup de code et Svelte, dans sa volonté de productivité, nous met à notre disposition un raccourci syntaxique. Ainsi, en préfixant le nom du store avec le signe $, nous pouvons accéder et interagir directement avec le contenu du store.

<h1>Counter : {countValue}</h1> peut ainsi être remplacé par <h1>Counter : {$counter}</h1> Cerise sur le gâteau, l’ajout de ce préfixe nous dispense d’utiliser subscribe et onDestroy(() => unsubscribe()) 🥳

<script>
  import counter from "./counter.js";
</script>
<h1>Counter : {$counter}</h1>

Concernant les boutons, nous pouvons les simplifier de la manière suivante :

<button on:click={() => $counter++}>+1</button>
<button on:click={() => $counter = 0}>Reset</button>

2.5.3 — Un store personnalisé

Il est possible d’aller plus loin avec les stores en y ajoutant des méthodes personnalisées. En effet, les writables étant des objets JavaScript, il est possible de les encapsuler dans un objet et y ajouter vos propres méthodes.

Pour commencer, il nous faut déstructurer l’objet writable dans une fonction qui retournera un objet constituant notre store personnalisé :

import { writable } from "svelte/store";
function createCounterStore() {
  const { subscribe, get, update } = writable(0);
}

Au niveau du retour de la fonction, il nous faut obligatoirement renvoyer la méthode subscribe pour bénéficier du raccourci syntaxique $. Dans un second temps, nous ajouterons une première fonction increment qui fera appel à update et une seconde fonction reset faisant appel à set. Nous obtenons ainsi :

import { writable } from "svelte/store";
function createCounterStore() {
  const { subscribe, set, update } = writable(0);
  // On renvoie subscribe et nos fonctions personnalisées
  return {
    subscribe,
    increment: () => update((n) => n + 1),
    reset: () => set(0),
  };
}

Pour finir avec notre store personnalisé, il nous faut instancier un nouvel objet et l’exporter :

import { writable } from "svelte/store";
function createCounterStore() {
  const { subscribe, set, update } = writable(0);
  return {
    subscribe,
    increment: () => update((n) => n + 1),
    reset: () => set(0),
  };
}
// On créé puis exporte notre nouveau store
const counter = createCounterStore();
export default counter;

Au niveau des composants, il n’est plus nécessaire d’utiliser $counter pour interagir avec la valeur du store et nous pouvons appeler directement nos nouvelles méthodes (notez la disparition du $ car nous utilisons les fonctions du store et non sa valeur 🙂) :

<button on:click={() => $counter++}>+1</button>
<button on:click={() => $counter = 0}>Reset</button>~~
<button on:click={counter.increment}>+1</button>
<button on:click={counter.reset}>Reset</button>

Pour afficher le contenu du store, aucun changement à signaler :

<!-- Toujours valable 🙂 -->
<h1>Counter : {$counter} !</h1>

Il faudrait tout un livre pour explorer l’ensemble des possibilités offertes par Svelte mais heureusement un tutoriel est à votre disposition à cette adresse : https://svelte.dev/tutorial/basics.

Ce dernier, de très bonne qualité, va vous permettre de découvrir une grande majorité des concepts de Svelte et vous rendre productif en environ une après-midi 🙂


3 — Quel avenir pour Svelte ?

Il est temps de prendre un peu de recul et d’évoquer l’avenir de Svelte en commençant par quelques défauts.

3.1 — Défauts de Svelte

Malgré ses qualités, certains défauts doivent toutefois être évoqués :

  • Éloignement du JavaScript final : le code généré est très différent de celui que vous écrirez dans votre fichier .svelte et cela peut être gênant notamment en cas d’erreur dans le code généré qu’il est plus difficile à analyser. De même, certaines personnes peuvent être gênées par ce principe en lui-même.

  • Eco-système jeune : comparés à Vue-Angular-React, les outils de développement sont moins avancés (pas de CLI) et beaucoup de librairies sur des besoins divers (formulaires, lecteurs vidéos, modales…) mais aucun ne font l’unanimité -encore- dans l’écosystème de Svelte, ce qui peut être compliqué pour un nouveau développeur Svelte.

  • Peu de demandes : soyons honnête, Svelte n’est pas encore une technologie très demandée pour le moment et pour cause Angular-Vue-React dominent le marché dû à leur ancienneté (et leurs qualités aussi 🙂). Par conséquent, pour un décideur, cela facilite les roulements au sein de leurs équipes et, côté développeurs, déjà productifs dans une technologie donnée (et l’appréciant sûrement), se re-former sur une nouvelle technologie n’est pas forcément enviable.

  • Comme entreprises notables utilisant Svelte, on peut citer Apple (qui diffuse des offres d’emploi demandant explicitement cette compétence), le New York Times (forcément dû à la présence de Rich Harris) et Spotify qui l’utilise notamment sur son site principal (certaines portions du site sont toutefois en React). On peut aussi citer Philips, Les Echos, Chess.com ou encore Rakuten (d’autres sont visibles à l’adresse suivante : https://svelte.dev/)

Bien sûr, certains de ces défauts sont dûs à la jeunesse du projet, la version 3 de Svelte étant sortie en avril 2019, mais grâce à une communauté active sur Discord, espérons que ces soucis disparaîtront un jour 😉.

3.2 — Trois géants qui évoluent aussi

Dans l’univers des librairies/framework front, trois géants sont déjà présents que nous avons évoqué tout au long de cet article :

Et bien que Svelte utilise la compilation comme source d’innovation, ces trois librairies évoluent aussi et reprennent dorénavant à leur compte les avantages de la compilation :

  • Vue.js dans sa version 3, analysera votre code pour optimiser son Virtual DOM et ne conserver que les comparaisons nécessaires

  • Angular avec Ivy, analyse aussi votre code pour diminuer drastiquement le poids du bundle final en retirant toutes les fonctions non-utilisées.

  • React de son côté n’a aucune évolution connue basée sur une analyse du code. Nous pouvons toutefois noter une expérimentation d’un des créateurs de Webpack qui a tenté de transformer du code React en équivalent VanillaJs. En résultat, un bundle de 4.3 Ko, bien maigre comparé au 115 Ko qu’on obtiendrait en temps normal et prouvant que la compilation pouvait avoir un avenir au sein de React. Cette expérimentation est disponible à cette adresse : https://github.com/sokra/rawact.

À noter toutefois qu’en mai 2020, Microsoft a introduit un système de création de sites statiques et a retenu quatre technologies pour ses tutoriels : React, Angular, Vue et… Svelte ! Un signe qui semble indiquer que Microsoft le considère comme une technologie suscitant assez d’engouement pour le prendre en considération.

4 — F.A.Q

Comment fonctionne le routing dans un projet Svelte ?

Il existe une myriade de librairies de routing disponibles dans Svelte mais je vais mettre les deux librairies dont j’ai le plus entendu parler :

  • SvelteKit : le template officiel d’un projet Svelte (en alpha depuis le 23 mars 2021) et se basant sur Vite 2 et inspiré par Nextjs. Pas de support de TypeScript pour le moment ni de SCSS ou LESS mais ils sont prévus pour la version 1.0 du projet.

  • Svelte-routing : qui permet de créer un système de manière similaire à React :

<div>
  <Route path="blog/:id" component="{BlogPost}" />
  <Route path="blog" component="{Blog}" />
  <Route path="about" component="{About}" />
  <Route path="/"><Home /></Route>
</div>
  • Routify : qui fonctionne par système de fichiers. La hiérarchie de vos fichiers correspondra ainsi à vos URLs :


Comment tester mes composants ?

Il existe plusieurs librairies permettant de tester ces composants :


Quelle est la compatibilité en termes de navigateur ?

La compatibilité va dépendre de deux éléments : la compatibilité des fonctions internes de Svelte et de votre code.

Le code interne de Svelte est compatible avec Internet Explorer 11 et, bien que je n’ai pas à disposition de données précises pour les autres navigateurs, le support de IE 11 me laisse serein concernant la prise en compte de Firefox, Chrome, Safari… 🙂


Peut-on ajouter Sass ?

C’est possible mais cela n’est pas inclus dans le template Svelte par défaut. Pour utiliser Sass, il faut installer quelques packages et ajouter quelques lignes dans la configuration Rollup du projet. Exemple de package : https://www.npmjs.com/package/svelte-preprocess-sass.


Les stores utilisent-ils les Observables ?

Non, au niveau interne, Svelte stocke les fonctions dans un tableau (lors du subscribe) et itère sur l’ensemble des fonctions du tableau après un update ou un set.


Peut-on utiliser Redux ?

Même s’il serait regrettable de ne pas profiter du fonctionnement natif des stores au sein de Svelte (et surtout du raccourci $), il est tout à fait envisageable d’inclure Redux au sein de votre projet. Redux étant une librairie JavaScript comme une autre après tout 🙂

Conclusion

L’approche compilateur choisie par Svelte nous apporte son lot d’améliorations : plus de performance, poids réduit et le tout avec moins de code.

Mais, au final quel avenir pour Svelte ? Cela va dépendre principalement de l’engouement des développeurs et leur volonté de lui donner sa chance dans un projet (sûrement de faible envergure pour commencer). C’est d’ailleurs ce que je vous conseille afin de mieux appréhender Svelte et développer votre propre opinion 🙂.

Si vous souhaitez un retour d’expérience d’une transposition d’un site React vers Svelte, je vous conseille de lire cet article de Mathieu Marchois :

SvelteJS, plus qu’une simple alternative à React, Vue ou Angular, où l’auteur explique notamment que suite à la réécriture en Svelte, le nombre de lignes du projet a chuté de 25000 à 8000 !

Mon avis

Pour ma part, j’ai découvert Svelte via la conférence “Rethink reactivity” qui m’a donné envie de m’y intéresser plus longuement. Et après avoir parcouru le tutoriel (très bien fait, je le re-précise 😊), j’ai expérimenté Svelte sur des projets personnels (que je ne finis jamais… 😔) et je dois avouer que l’expérience développeur me semble un grand cran au-dessus de React, malgré les besoins de modifier la configuration Rollup pour supporter Sass par exemple.

Clairement, Svelte fera parti de ma stack de prédilection en remplacement de React, si jamais l’occasion se présente.

Pour aller plus loin :

La suite logique de cet article est la conférence “Rethink reactivity” où Rich Harris y présente la version 3 de Svelte ainsi que ses griefs contre React :

Rethinking reactivity


Pour revoir la vidéo dans son format d’origine, je vous invite à consulter la vidéo suivante :

SFEIR Talks #10 - Svelte : un concurrent de poids face à React-Angular-Vue ?