Et si on comparait deux frameworks en créant la même page d’accueil? Angular vs Svelte, c’est parti!

Introduction

Dans le deuxième épisode Angular, j’avais réalisé une première page et trouvé cela à la fois bien organisé et en même temps lourd à manipuler et maintenir (je ne suis toujours pas remis du coup des pictogrammes). Du coup, je me suis demandé ce que Svelte pouvait faire dans une situation similaire. Éléments de réponse.

Préparer le projet

Pour créer un projet avec Svelte, le plus simple est de cloner l’application d’exemple avec la commande:

    
1npx degit sveltejs/template ged12

NPX répond finalement ceci:

    
1npx: installed 1 in 1.479s
2> cloned sveltejs/template#HEAD to ged12

Ensuite, il faut aller dans le dossier ged12/ puis installer les dépendances avec les commandes:

    
1cd ged12
2npm install

Après quelques instants, NPM répond ce qui suit:

    
 1npm notice created a lockfile as package-lock.json. You should commit this file.
 2npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules/rollup/node_modules/fsevents):
 3npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
 4
 5added 96 packages from 126 contributors and audited 97 packages in 7.434s
 6
 76 packages are looking for funding
 8  run `npm fund` for details
 9
10found 0 vulnerabilities

(Note: on est content de savoir qu’il n’y a pas de vulnérabilités. Pas comme avec Angular).

Ensuite, on lance le serveur NPM avec un petit npm run dev qui répond ceci:

    
 1> svelte-app@1.0.0 dev /....../ged12
 2> rollup -c -w
 3
 4rollup v2.58.0
 5bundles src/main.js  public/build/bundle.js...
 6LiveReload enabled
 7created public/build/bundle.js in 1.3s
 8
 9[2021-10-24 11:34:20] waiting for changes...
10
11> svelte-app@1.0.0 start /....../ged12
12> sirv public --no-clear "--dev"
13
14
15  Your application is ready~! 🚀
16
17  - Local:      http://localhost:5000
18  - Network:    Add `--host` to expose
19
20────────────────── LOGS ──────────────────

Voilà, on peut ouvrir un browser à l’adresse http://localhost:5000 pour admirer le résultat suivant:

Page par défaut

Page par défaut

Customiser la page d’accueil

Pour customiser la page d’accueil, je vais ajouter Bulma puis FontAwesome à ma page dont le code de base est le suivant:

    
 1<div class="dark-wrapper">
 2		<section class="hero is-fullheight is-transparent">
 3			<div class="hero-head">
 4			</div>
 5			<div class="hero-body">
 6				<div class="container">
 7					<div class="columns is-vcentered">
 8						<div class="column is-5 landing-caption">
 9							<h1 class="title is-1 is-light is-semibold is-spaced main-title">HomeGED</h1>
10							<h2 class="subtitle is-6 is-light is-thin">Organiser facilement vos documents</h2>
11							<p>
12								<a class="button is-primary is-fat is-bold is-rounded" tabindex=-1>Connexion&nbsp;<i class="fas fa-sign-in-alt" aria-hidden="true"></i></a>
13								<a class="button is-fat is-bold is-rounded" tabindex=-2>Inscription&nbsp;<i class="fas fa-user" aria-hidden="true"></i></a>
14							</p>
15						</div>
16						<div class="column is-7">
17							<figure class="image">
18								<img src="project/page-home/home.jpg" alt="Librairie par Giammarco" class="ged-home-illu">
19							</figure>
20						</div>
21					</div>
22				</div>
23			</div>
24			<div class="hero-foot">
25				<div class="container">
26					<div class="tabs is-centered">
27					</div>
28				</div>
29			</div>
30		</section>
31	</div> 

Au préalable, j’ai bien sûr ajouté mon image home.jpg dans le dossier public/project/page-home.

Ajouter Bulma

J’ai copié les ressources Bulma dans le dossier public/ du projet. Ensuite, il faut modifier la page public/index.html comme suit (modifications en bleu):

    
 1<!DOCTYPE html>
 2<html lang="en">
 3<head>
 4	<meta charset='utf-8'>
 5	<meta name='viewport' content='width=device-width,initial-scale=1'>
 6	<title>HomeGED</title>
 7	<link rel='icon' type='image/png' href='/favicon.png'>
 8	<link rel='stylesheet' href='/global.css'>
 9	<link rel='stylesheet' href='/bulma/css/bulma.min.css'>
10	<link rel='stylesheet' href='/build/bundle.css'>
11	<script defer src='/build/bundle.js'></script>
12</head>
13<body>
14</body>
15</html>

Ensuite, j’ai modifié le fichier src/App.svelte pour ajouter ma page de base. J’ai remplacé le contenu du tag main par mon code puis j’ai ajouté le style de l’image dans le tag style. Le contenu du fichier est alors le suivant:

    
 1<script>
 2	export let name;
 3</script>
 4
 5<main>
 6	<div class="dark-wrapper">
 7		<section class="hero is-fullheight is-transparent">
 8			<div class="hero-head">
 9			</div>
10			<div class="hero-body">
11				<div class="container">
12					<div class="columns is-vcentered">
13						<div class="column is-5 landing-caption">
14							<h1 class="title is-1 is-light is-semibold is-spaced main-title">HomeGED</h1>
15							<h2 class="subtitle is-6 is-light is-thin">Organiser facilement vos documents</h2>
16							<p>
17								<a class="button is-primary is-fat is-bold is-rounded" tabindex=-1>Connexion&nbsp;<i class="fas fa-sign-in-alt" aria-hidden="true"></i></a>
18								<a class="button is-fat is-bold is-rounded" tabindex=-2>Inscription&nbsp;<i class="fas fa-user" aria-hidden="true"></i></a>
19							</p>
20						</div>
21						<div class="column is-7">
22							<figure class="image">
23								<img src="project/page-home/home.jpg" alt="Librairie par Giammarco" class="ged-home-illu">
24							</figure>
25						</div>
26					</div>
27				</div>
28			</div>
29			<div class="hero-foot">
30				<div class="container">
31					<div class="tabs is-centered">
32					</div>
33				</div>
34			</div>
35		</section>
36	</div>
37</main>
38
39<style>
40	.ged-home-illu {
41	    border: 1px solid #222222;
42	    border-radius: 6px;
43	}
44</style>

On relance le serveur NPM puis le navigateur affiche cette page:

Page d&rsquo;accueil

Page d’accueil

Soyons honnêtes: à ce stade, j’en suis à moins de 10 minutes pour obtenir la première page. Et le projet pèse 51Mo (soit dix fois moins qu’avec Angular -je sais, le Go n’est plus très cher mais tout de même-).

Ajouter Font Awesome

Ici, comme pour Bulma, j’ai copié les ressources FontAwesome dans le dossier public/ puis j’ai modifié le fichier public/index.html (modifications en bleu):

    
 1<!DOCTYPE html>
 2<html lang="en">
 3<head>
 4	<meta charset='utf-8'>
 5	<meta name='viewport' content='width=device-width,initial-scale=1'>
 6	<title>HomeGED</title>
 7	<link rel='icon' type='image/png' href='/favicon.png'>
 8	<link rel='stylesheet' href='/global.css'>
 9	<link rel='stylesheet' href='/bulma/css/bulma.css'>
10	<link rel='stylesheet' href='/fontawesome/css/fontawesome.min.css'>
11	<link rel='stylesheet' href='/build/bundle.css'>
12	<script defer src='/build/bundle.js'></script>
13</head>
14<body>
15</body>
16</html>

Ensuite, du fait de l’organisation des fichiers imposée par Svelte, il faut tricher un peu. En effet, si on lie le fichier fontawesome/css/solid.min.css dans index.html, les icônes ne sont pas affichées. La raison est simple: les liens vers les fichiers de fontes (TTF, WOFF, etc) sont incorrects. Par défaut, ils ont cette forme: url("../webfonts/fa-solid-900.ttf"). Comme le serveur NPM cherche les fichiers dans le dossier public/, il va chercher le dossier webfonts/ au même niveau que public/ et donc ne rien trouver (puisque ce dossier est dans public/fontawesome). L’astuce est alors de ne pas utiliser le fichier fontawesome/css/solid.min.css mais d’ajouter au début du fichier public/global.css les lignes suivantes (en bleu, la modification importante):

    
 1@font-face {
 2  font-family: 'Font Awesome 5 Free';
 3  font-style: normal;
 4  font-weight: 900;
 5  font-display: block;
 6  src: url("/fontawesome/webfonts/fa-solid-900.eot");
 7  src:
 8  	url("/fontawesome/webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"),
 9  	url("/fontawesome/webfonts/fa-solid-900.woff2") format("woff2"),
10	url("/fontawesome/webfonts/fa-solid-900.woff") format("woff"),
11	url("/fontawesome/webfonts/fa-solid-900.ttf") format("truetype"),
12	url("/fontawesome/webfonts/fa-solid-900.svg#fontawesome") format("svg"); }
13
14.fa, .fas {
15  font-family: 'Font Awesome 5 Free';
16  font-weight: 900; 
17}

On peut maintenant relancer le serveur NPM et constater que les icônes s’affichent:

Les icônes sont affichées

Les icônes sont affichées

Validation HTML et Javascript

Svelte propose une fonctionnalité intéressante puisque, lors de la compilation, une validation du HTML et du Javascript est réalisée. Par exemple, sur la page décrite dans cet article, Svelte va indiquer plusieurs problèmes:

    
 1(!) Plugin svelte: A11y: <a> element should have an href attribute
 2src/App.svelte
 315:               <h2 class="subtitle is-6 is-light is-thin">Organiser facilement vos documents</h2>
 416:               <p>
 517:                 <a class="button is-primary is-fat is-bold is-rounded" tabindex=-1>Connexion&nbsp;<i class="fas fa-sign-in-alt" aria-hidden="true"></i></a>
 6                    ^
 718:                 <a class="button is-fat is-bold is-rounded" tabindex=-2>Inscription&nbsp;<i class="fas fa-user" aria-hidden="true"></i></a>
 819:               </p>
 9src/App.svelte
1016:               <p>
1117:                 <a class="button is-primary is-fat is-bold is-rounded" tabindex=-1>Connexion&nbsp;<i class="fas fa-sign-in-alt" aria-hidden="true"></i></a>
1218:                 <a class="button is-fat is-bold is-rounded" tabindex=-2>Inscription&nbsp;<i class="fas fa-user" aria-hidden="true"></i></a>
13                    ^
1419:               </p>
1520:             </div>
16(!) Plugin svelte: App has unused export property 'name'. If it is for external reference only, please consider using `export const name`
17src/App.svelte
181: <script>
192:   export let name;
20                ^
213: </script>
224: 

Les deux boutons n’ont pas d’attribut href, ce qui est dommage pour des liens. Quand au script, il exporte une variable non initialisée et inutilisée.

Conclusion

Bon, il n’y a pas photo! En moins de 20 minutes on arrive au même résultat qu’Angular, sans partir dans des délires technologiques. La vitesse de compilation est incomparable, Svelte va tellement (mais tellement) plus vite. Je me demande si je ne vais pas laisser tomber Angular. Affaire à suivre.