Pourquoi Svelte avec TypeScript : guide complet ?
Dans un monde où la vitesse et l'efficacité sont essentielles, le choix d'un framework JavaScript peut faire une différence cruciale dans le développement de votre application web. Svelte est connu pour son rendu performant et sa petite taille finale, tout en offrant des fonctionnalités modernes comme les props, les slots, et la reactivité réactive. TypeScript, quant à lui, ajoute une couche supplémentaire de sécurité et de lisibilité au code grâce aux types statiques.
En combinant ces deux technologies, vous obtenez un outil puissant pour construire des applications modernes et évolutives. Un cas concret d'utilisation serait le développement d'un système interne pour une entreprise, nécessitant une application robuste, performante et bien testée.
Prerequis
Pour suivre ce guide, vous aurez besoin de :
- Node.js (v14 ou plus)
- npm (v6 ou plus)
- Un éditeur de code (VSCode recommandé)
Installez Node.js en visitant nodejs.org et suivez les instructions d'installation. Cela installera également npm.
Concepts fondamentaux
1. Création d'un projet Svelte avec TypeScript
Commencez par créer un nouveau projet Svelte avec TypeScript :
npx degit sveltejs/template svelte-ts-project
cd svelte-ts-project
npm install
Cela créera un nouveau projet Svelte avec une structure de base et les dépendances nécessaires pour l'utilisation de TypeScript.
2. Types et Props
Les props sont un moyen d'envoyer des données à des composants enfants en Svelte. Avec TypeScript, vous pouvez définir le type des props :
<script lang="ts">
export let title: string;
export let description?: string; // Prop optionnelle
</script>
<h1>{title}</h1>
{#if description}
<p>{description}</p>
{/if}
3. State et Reactivité
Svelte utilise un système de reactivité réactif, ce qui signifie que les composants se mettent à jour automatiquement lorsque leur état change :
<script lang="ts">
import { writable } from 'svelte/store';
export let count = writable(0);
const increment = () => {
count.update(n => n + 1);
};
const decrement = () => {
count.update(n => n - 1);
};
</script>
<button on:click={decrement}>-</button>
<span>{count}</span>
<button on:click={increment}>+</button>
4. Events et Handlers
Les gestionnaires d'événements en Svelte peuvent être définis en utilisant des fonctions :
<script lang="ts">
let inputValue = '';
const handleInputChange = (event: Event) => {
inputValue = (event.target as HTMLInputElement).value;
};
const handleSubmit = () => {
alert(`Input value: ${inputValue}`);
};
</script>
<input type="text" bind:value={inputValue} on:input={handleInputChange} />
<button on:click={handleSubmit}>Submit</button>
Mise en pratique : projet fil rouge
Étape 1 : Création du projet
Commencez par créer un nouveau projet Svelte avec TypeScript :
npx degit sveltejs/template svelte-ts-todo-app
cd svelte-ts-todo-app
npm install
Étape 2 : Structure de base des composants
Créez les fichiers suivants dans le répertoire src :
Todo.svelteApp.svelte
Étape 3 : Composant TodoItem
Dans Todo.svelte, créez un composant pour une tâche individuelle :
<script lang="ts">
export let todo: { id: number, text: string, completed: boolean };
export let onToggleComplete: (id: number) => void;
export let onDelete: (id: number) => void;
</script>
<style>
.todo {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.checkbox {
margin-right: 16px;
}
.text {
flex-grow: 1;
}
.delete-button {
cursor: pointer;
}
</style>
<div class="todo">
<input type="checkbox" checked={todo.completed} on:change={() => onToggleComplete(todo.id)} />
<span class:text-strikethrough:={todo.completed}>{todo.text}</span>
<button class="delete-button" on:click={() => onDelete(todo.id)}>Delete</button>
</div>
Étape 4 : Composant App
Dans App.svelte, créez le composant principal :
<script lang="ts">
import { writable } from 'svelte/store';
import Todo from './Todo.svelte';
interface TodoItem {
id: number;
text: string;
completed: boolean;
}
const todos = writable<TodoItem[]>([
{ id: 1, text: 'Learn Svelte', completed: false },
{ id: 2, text: 'Build a todo app', completed: true }
]);
const addTodo = (text: string) => {
if (text.trim()) {
todos.update(todosList => [
...todosList,
{ id: Date.now(), text, completed: false }
]);
}
};
const toggleComplete = (id: number) => {
todos.update(todosList =>
todosList.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
const deleteTodo = (id: number) => {
todos.update(todosList =>
todosList.filter(todo => todo.id !== id)
);
};
</script>
<style>
h1 {
margin-bottom: 24px;
}
.todo-list {
list-style-type: none;
padding: 0;
}
.input-group {
display: flex;
align-items: center;
margin-bottom: 16px;
}
input[type="text"] {
flex-grow: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 8px;
}
button {
padding: 8px 16px;
border: none;
background-color: #007bff;
color: white;
border-radius: 4px;
cursor: pointer;
}
</style>
<h1>Todo App</h1>
<div class="input-group">
<input type="text" bind:value={newTodoText} placeholder="Add a new todo" />
<button on:click={() => addTodo(newTodoText)}>Add</button>
</div>
<ul class="todo-list">
{#each $todos as todo (todo.id)}
<li>
<Todo
{todo}
onToggleComplete={toggleComplete}
onDelete={deleteTodo}
/>
</li>
{/each}
</ul>
Étape 5 : Exécution du projet
Exécutez le projet avec la commande suivante :
npm run dev
Ouvrez votre navigateur et accédez à http://localhost:5000 pour voir votre application en cours d'exécution.
Erreurs frequentes et debugging
1. Prop non défini
Erreur :
Property 'title' does not exist on type '{}'.
Correction :
<script lang="ts">
export let title: string = ''; // Définition par défaut
</script>
2. Erreur de typage en utilisant les hooks
Erreur :
Type 'null' is not assignable to type 'string'.
Correction :
<script lang="ts">
import { onMount } from 'svelte';
let content: string | null = null;
onMount(async () => {
const response = await fetch('https://api.example.com/data');
content = await response.text();
});
</script>
3. Erreur de typage dans les événements
Erreur :
Type 'Event' is not assignable to type '{ target: HTMLInputElement }'.
Correction :
<script lang="ts">
let inputValue = '';
const handleInputChange = (event: Event) => {
const target = event.target as HTMLInputElement;
inputValue = target.value;
};
</script>
Pour aller plus loin
1. Optimisation des performances
- Utilisez les hooks
onMountetonDestroypour gérer la mise à jour des composants. - Évitez les rendus inutiles en utilisant le concept de memoization.
2. Intégration avec des bibliothèques tierces
- L'Intégrez Svelte avec des bibliothèques comme
sveltestrappour des composants UI améliorés. - Utilisez la fonction
getContextetsetContextpour partager des données entre les composants.
3. Tests unitaires
- Utilisez Jest et Svelte Testing Library pour écrire des tests unitaires pour vos composants.
Défi pratique :
Créez un mini-projet réaliste en utilisant Svelte avec TypeScript. Vous pouvez choisir de développer une application comme un simple gestionnaire de notes ou un petit assistant virtualisé. Assurez-vous d'inclure les concepts fondamentaux vus dans ce guide, ainsi que des tests unitaires pour chaque composant.