La documentation technique d’un projet est malheureusement une phase souvent négligée, voire complètement sacrifiée par manque de temps.
Pourtant il nous est tous déjà arrivé de devoir faire un petit correctif sur un projet que nous n’avons pas développé. L’apprentissage des rouages de ce dernier se fait plus ou moins lentement et plusieurs questions peuvent alors se poser :
- “Est-ce que je peux utiliser un composant existant ou dois-je créer le mien ?”
- “Ce composant a l’air de répondre à mon besoin, mais comment en être sûr à 100% ?”
- “Je dois faire évoluer un composant mais j’ai un peu peur de tout casser, que faire ?”
Etc, etc…
Qu’est-ce que Storybook ?
Storybook est un outil Open-Source permettant de développer des composants isolés pour React, Vue et Angular.
Voici la vidéo de présentation :
Vous trouverez également ici tout un tas d’exemples d’utilisation de Storybook.
Intégration dans un projet
L’intégration de Storybook dans les projets a été simplifiée au maximum, si bien qu’une seule ligne de commande suffit
npx -p @storybook/cli sb init --type <le-framework-utilisé>
Donc par exemple pour un projet Angular
npx -p @storybook/cli sb init --type angular
Cela va faire plusieurs choses :
- Créer un dossier .storybook à la racine du projet qui contiendra entre autres
- Un fichier addons.js (nous reviendrons plus tard sur ce fichier)
- 2 fichiers de configurations
- Créer un dossier stories avec un fichier index.stories.js qui contient quelques exemples.
- Ajouter des devDependencies au package.json ainsi que 2 scripts.
Nous pouvons maintenant exécuter la commande suivante
npm run storybook
Une page doit automatiquement s’ouvrir et doit ressembler à peu de chose près à ceci :
Vous pouvez déjà tester quelques fonctionnalités, par exemple en allant dans Button > with some emoji and action et en cliquant sur le bouton vous devriez voir qu’une action a été lancée dans le panel Actions
Contenu d’une story
Regardons maintenant de plus près le fichier index.stories.js et attardons nous plus en détail sur sa composition.
storiesOf
La méthode storiesOf permet de créer une nouvelle story, nous pouvons lui donner le nom que l’on souhaite.
Attention toutefois car cela définit également l’arborescence de vos stories. Par exemple :
storiesOf(‘toto’) va créer l’arborescence suivante
- toto
storiesOf(‘toto|tata’) va créer l’arborescence suivante
- toto
- tata
storiesOf(‘toto|tata\titi’) va créer l’arborescence suivante
- toto
- tata
- titi
- tata
Etc etc…
add
La méthode add est directement liée à la méthode storiesOf et permet, comme son nom l’indique, d’ajouter un cas d’utilisation au composant testé. En terme d’arborescence cela va ajouter le cas comme fils direct du dossier définit dans la méthode storiesOf.
Par exemple
storiesOf(‘toto’).add(‘tata’) va créer l’arborescence suivante
- toto
- tata
Sauf que cette fois-ci tata ne sera pas considéré comme un dossier mais comme un fichier.
Le 2e paramètre de la méthode add retourne le composant à tester dans la configuration souhaitée.
En React cela donnerait
import React from 'react'; import { storiesOf } from '@storybook/react'; import { Button } from '@storybook/react/demo'; storiesOf('Button', module) .add('with text', () => ( <Button>Hello Button</Button> )) .add('with emoji', () => ( <Button><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button> ));
En Vue
import Vue from 'vue'; import { storiesOf } from '@storybook/vue'; import MyButton from './Button.vue'; storiesOf('Button', module) .add('with text', () => '<my-button>with text</my-button>') .add('with emoji', () => '<my-button>😀 😎 👍 💯</my-button>') .add('as a component', () => ({ components: { MyButton }, template: '<my-button :rounded="true">rounded</my-button>' }));
En Angular
import { storiesOf } from '@storybook/angular'; import { Button } from '@storybook/angular/demo'; storiesOf('My Button', module) .add('with text', () => ({ component: Button, props: { text: 'Hello Button', }, })) .add('with emoji', () => ({ component: Button, props: { text: '😀 😎 👍 💯', }, }));
Le 3e paramètre permet d’éventuellement ajouter une note à notre test. Cette note peut prendre différents formats, notamment le markdown, ce qui permet de documenter de manière très poussée.
Voici un exemple sur un projet existant :
En terme de code cela donnerait par exemple en Angular
import { storiesOf } from '@storybook/angular'; import { Button } from '@storybook/angular/demo'; storiesOf('Button', module) .add( 'with some emoji', () => ({ component: Button, props: { text: '😀 😎 👍 💯', }, }), { notes: <ici les notes à afficher au format souhaité> } )
Créer sa première story
Si vous jeter un coup d’oeil au fichier config.js qui se trouve dans le dossier .storybook vous remarquerez que Storybook scanne votre projet à la recherche des fichiers se terminant par stories.js.
Pour créer une nouvelle story il suffit donc simplement de créer un nouveau fichier se terminant par stories.js, n’importe où dans le projet.
Ajout d’addons
Lorsqu’on initialise Storybook, nous avons la possibilité de voir les actions lancées et/ou les notes. Il est possible par la suite d’en ajouter d’autres.
Rajoutons ensemble un addon permettant de modifier la taille de notre viewport.
Commençons par installer la dépendance de dev
npm i --save-dev @storybook/addon-viewport
Puis ajouter la ligne suivante à la fin du fichier addons.js
import '@storybook/addon-viewport/register';
Et c’est tout ! Normalement une icône devrait apparaître à coté des notes. Cela permettra de modifier la taille du viewport et donc de tester la responsivité de notre composant.
En pratique
La bonne pratique en terme d’architecture est de regrouper l’ensemble des cas possibles d’un composant dans la même story pour avoir rapidement une vue synthétique.
Et pour tester que notre composant réagit bien au changement de taille
Conclusion
Storybook est un outil très facile à installer et à prendre en main. Il permet de tester en profondeur les composants (fonctionnalités, réactivé au changement de taille, etc). L’outil vous permet indirectement de proposer aux utilisateurs une liste des composants utilisables avec une documentation attachée à chacun d’eux, et ça, c’est top !