StimulusJS sur Rails 101

Younes Serraj
Younes Serraj23 oct. 2018

StimulusJS est le nouveau framework Javascript qui a été publié cette année

StimulusJS est le nouveau framework Javascript qui a été publié cette année

StimulusJS est le nouveau framework Javascript qui a été publié cette année (2018) par DHH, le créateur de Ruby on Rails.

Il s'agit d'un guide pratique pour commencer à utiliser StimulusJS dans un projet Ruby on Rails (avec un bonus à la fin 😉 ). Vous trouverez également à la fin de l'article un lien vers un projet qui utilise tout ce qui est présenté dans cet article pour que vous puissiez l'essayer sans attendre.

Vous pourriez être tenté de le comparer à d'autres frameworks tels que ReactJS, Angular ou VueJS mais vous ne devriez pas. StimulusJS ne joue pas dans leur domaine puisqu'il n'a pas l'intention de construire des composants d'interface utilisateur, de synchroniser le frontend et le backend en utilisant AJAX ou tout autre truc du genre.

À ce jour, l'unique tâche de StimulusJS consiste à lier des comportements à des éléments HTML.

Un véritable concurrent serait la méthode .on() de JQuery. JQuery est génial mais il vous oblige à définir vos liens dans des fichiers Javascript, ce qui signifie que vous ne pouvez pas savoir si un élément HTML a un comportement lié à moins de lire tous les fichiers Javascript. Je préfère l'approche de StimulusJS : lire les attributs d'un élément HTML pour savoir si un comportement est lié ou non. Ne vous méprenez pas, même si je délègue la partie liaison à StimulusJS, j'utilise toujours JQuery pour me faciliter la vie en matière de développement frontal (appels AJAX, etc.). Les deux fonctionnent bien ensemble.


Un mot rapide sur JQuery et Turbolinks

Si vous avez déjà utilisé JQuery et Turbolinks ensemble, vous serez heureux d'apprendre qu'il n'y en a plus :

$(document).ready()

Et plus de ça :

$(document).on('turbolinks:load', function() {})

StimulusJS s'en occupe maintenant :) Mettez votre code dans vos contrôleurs et laissez le framework faire la magie. Quels contrôleurs ? Comment ? Où ? Nous allons en parler dans un instant. Installons d'abord les dépendances pour exécuter StimulusJS dans un projet Ruby on Rails, puis nous verrons comment l'utiliser.


Un mot rapide sur les contrôleurs

Cela peut être évident pour les développeurs frontaux expérimentés, mais je veux m'assurer que personne ne s'y perd :


Rails a ses contrôleurs sous  app/controllers and StimulusJS a ses contrôleurs sous app/javascript/controllers. Il n'y a aucun lien entre eux, aucun.


Dans cet article, lorsque je fais référence à un contrôleur, je parle d'un contrôleur StimulusJS.


Installer StimulusJS dans Rails en utilisant Yarn et Webpacker


1. Installer Yarn

Rails est passé à Yarn pour la gestion des paquets Javascript. Yarn a une grande communauté, gère les dépendances, fournit une mise en cache, etc. Maintenant, lorsque vous avez besoin d'ajouter une dépendance à votre projet (Javascript mais aussi les feuilles de style), je vous suggère fortement de chercher d'abord le paquet Yarn avant de chercher la gemme.


TL;DR : Bootstrap, MomentJS, ChartJS, Fontawesome, etc. : ajoutez-les via Yarn.

Pour ajouter un paquet, utilisez la boîte de recherche dans https://yarnpkg.com/ pour le trouver, puis installez-le en utilisant yarn add [package name].


2. Installer Webpacker

De nos jours, les applications Rails ne se résument pas toujours à du simple code Ruby on Rails.

Vous avez souvent une API Rails, un frontend Javascript React/Vue/Angular/YouNameIt et quelques feuilles de style SCSS pour rendre le tout joli.

Dans ce contexte, nous considérons la partie frontale Javascript comme une application à part entière car elle est souvent accompagnée de ses propres contrôleurs, routeurs, modèles, etc.

Il y a deux choses à garder à l'esprit :

  • Gardez votre base de code propre. Séparez ce qui est spécifique à votre interface utilisateur React/quelque chose du reste de votre application (c'est-à-dire mettez le code de l'application JS dans un sous-répertoire spécifique de votre projet Rails)

  • Tirez parti des excellents outils disponibles aujourd'hui, tels que ES6, SCSS, etc.

Webpack est là pour prendre en charge la compilation ES6 et SCSS, la minification, la gestion des dépendances et bien plus encore.

Webpacker est la gemme qui ajoute Webpack à un projet Rails.

Lorsque vous utilisez webpacker, un nouveau sous-répertoire est ajouté à votre projet : app/javascript/packs/.Chaque pack est un module que vous pouvez inclure dans vos vues. Votre application StimulusJS sera un module à inclure dans vos vues (voir comment dans la section suivante).

  • Ajouter gem 'webpacker' to your Gemfile et exécuter bundle install.

  • Exécuter la commande suivante: rails webpacker:install

Jetez un coup d'œil aux fichiers suivants pour vous faire une idée de ce qui se passe :

  • config/webpacker.rb

  • config/webpack/*

  • app/javascript/packs/application.js


3. Installer StimulusJS

Il existe une commande très pratique pour ajouter StimulusJS à votre projet :
rails webpacker:install:stimulus

Cela va installer StimulusJS, créer un répertoire qui contiendra vos contrôleurs et ajouter quelques lignes à votre application.js pour initialiser le framework.

Jetez un coup d'œil à ce qui suit :

  • app/javascript/packs/application.js

  • app/javascript/packs/controllers/

Maintenant, faites en sorte que Rails inclue votre premier pack dans app/views/layouts/application.html.erb. Si votre pack est app/javascript/packs/application.js, puis ajoutez ce qui suit :

Installer StimulusJS



Exemple de Hello World

Nous sommes maintenant prêts à passer au sujet suivant : comment utiliser StimulusJS.


Avant d'entrer dans le détail de son fonctionnement, j'aimerais que vous lisiez l'extrait de code suivant :

app/views/younameit/index.html.erb:

comment utiliser StimulusJS

app/javascript/controllers/mycontroller_controller.js:

app/javascript/controllers/mycontroller_controller.js

Ce qu'il fait est assez simple : lorsque vous cliquez sur le bouton, il affiche "Hello World !".


Maintenant que vous avez une idée du fonctionnement de StimulusJS, décomposons tout.


Lier un élément HTML à un contrôleur StimulusJS (data-controller)

La toute première étape consiste à lier une partie de votre DOM HTML à un contrôleur.

  1. Créez un contrôleur (voir l'exemple ci-dessus ou)

  2. Encadrez la sous-partie du document HTML que vous voulez lier à ce contrôleur dans un élément qui aura un attribut data-controller. Par exemple: <div data-controller="mycontrollername">...</div>

Lier un élément HTML à un contrôleur StimulusJS

C'est tout. Maintenant ce div et tout ce qu'il contient peut interagir avec le contrôleur mycontrollername.


Ne tombez pas dans ce piège

Si le nom de fichier de votre contrôleur contient des traits de soulignement, le nom correspondant à utiliser dans votre document HTML a des traits de soulignement (_) remplacés par des traits d'union (-).

  • Nom de fichier: app/javascript/controllers/content_loader_controller.js (use underscores)

  • Nom du controller: content-loader (use hyphens) <div data-controller="content-loader">...</div>


Liaison de données (données-cible)

C'est l'utilisation la plus basique de StimulusJS : référencer un élément HTML dans un contrôleur afin d'y accéder ultérieurement. Nous appelons cela une cible (un descripteur de cible pour être exact).

Tout d'abord, choisissez un nom pour chaque cible et listez-les dans le tableau statique targets de votre contrôleur. 

Liaison des données

Ajoutez ensuite un attribut data-target="controllername.targetname" à chaque élément HTML ciblé.

Ajouter un attribut data-target="controllername.targetname" à chaque élément HTML ciblé.

Comment accéder à une cible depuis le contrôleur ? Nous le faisons en appelant, pour une cible nommée outputthis.outputTarget.

Une cible nommée output : this.outputTarget

Puisque dans notre exemple, la output est un span, nous pouvons modifier son contenu via l'attribut textContent. Cela signifie que this.outputTarget.textContent = 'Call me daddy' affichera Call me daddy dans la vue.


Une cible pour tous les cas

Bien que le cas d'utilisation de base soit une cible pour un élément HTML, vous pouvez en fait avoir une cible pour plusieurs éléments HTML. Vous y accédez alors par le biais du tableau this.outputTargets (au pluriel).

Une seule cible pour les gouverner toutes
Vous y accédez ensuite par le biais du tableau this.outputTargets


Comportement déclenché par un événement (données-action)

Vous voulez appeler une méthode lorsqu'un événement particulier (clic, pression sur une touche, etc.) se produit ?

Utilisez l'attribut data-action sur votre élément HTML.
L'attribut data-action, comme vous pouvez facilement le deviner, nous permet d'appeler une méthode du contrôleur sur un certain événement. Dans le présent exemple :

  • L'événement est click

  • Le controleur est mycontroller

  • La méthode à appeler est say_hello

Comportement déclenché par un événement

Vous pouvez écouter de nombreux événements tels que click, dbclick, keyup, etc.


Initialiser votre contrôleur à partir de la vue (data-*)

Parfois, vous souhaitez réutiliser un même contrôleur plusieurs fois dans la même vue pour différents éléments (une instance de contrôleur différente pour chaque élément).

Disons que nous avons un blog avec des commentaires. Les commentaires abusifs peuvent être signalés à l'administrateur. Chaque commentaire doit être affiché et avoir son propre bouton de rapport. Le rapport doit être asynchrone (AJAX).

Il est évident que nous n'avons besoin que d'un seul contrôleur StimulusJS pour fournir ce comportement simple : attraper un événement de clic sur un bouton et appeler une méthode de contrôleur qui fera tous les appels AJAX nécessaires pour signaler le commentaire abusif. Chaque commentaire peut ensuite être lié à une instance différente du contrôleur.

Initialiser votre contrôleur à partir de la vue

Puisque nous ne pouvons pas envoyer un argument dans data-action (<button data-action="click->comment-report#report(41)">...</button> doesn’t work), nous devons trouver comment initialiser chaque instance avec l'id du commentaire pour que l'appel AJAX soit fait à la bonne url.

Une fois de plus, c'est très simple : lorsque vous utilisez la fonction data-controller dans un élément HTML, vous pouvez également ajouter d'autres attributs data-<controller name>-<attribute name>. Par exemple data-comment-report-comment-id="42":

data-comment-report-comment-id="42"
Notez que data-comment-report-comment-id utilise des mots en minuscules séparés par des traits d'union

Notez que data-comment-report-comment-id utilise des mots en minuscules séparés par des tirets alors que this.data.get("commentId")utilise une syntaxe en minuscules camelCase. 


Pour résumer

Il existe trois outils principaux :

  • data-controller : si votre fichier de contrôleur est nommé progress_tracker_controller.js, vous faites <div data-controller="progress-tracker">...</div>

  • data-target : pour un name cible dans votre contrôleur, vous faites <div data-controller="progress-tracker"><p data-target="progress-tracker.name"></p></div> et y accéder en utilisant this.nameTarget.

  • data-action : appeler la méthode rule_them_all lorsqu'un événement de click survient en ajoutant ladite méthode au contrôleur et <div data-controller="progress-tracker"><p data-action="click->progress-tracker#rule_them_all">Click me</p></div>

Il existe également ces 3 méthodes que je ne vais pas aborder dans cet article, notez simplement qu'elles existent et qu'elles peuvent s'avérer utiles une fois que vous vous serez familiarisé avec StimulusJS et que vous aurez besoin de faire des choses plus avancées.

  • initialize()est invoqué une fois, lorsque le contrôleur est instancié pour la première fois.

  • connect(): est invoqué à chaque fois que le contrôleur est connecté au DOM.

  • disconnect(): est invoqué à chaque fois que le contrôleur est déconnecté du DOM.

À partir de là, vous pouvez faire à peu près tout ce que vous voulez. Vous pouvez importer JQuery dans votre contrôleur et faire des appels AJAX, changer le style d'un élément, etc. En fait, vous déléguez la partie gestion des liaisons et des événements à StimulusJS et vous faites le reste avec les outils de votre choix. Vous pouvez même sauter la partie cible et utiliser les sélecteurs JQuery, mais pourquoi s'embêter quand StimulusJS le fait pour vous ?


Bonus: Ajouter StimulusJS à ActiveAdmin

Si vous avez besoin d'offrir une meilleure expérience utilisateur sur votre tableau de bord ActiveAdmin, je vous propose d'y ajouter un peu de sucre en utilisant Stimulus. Le principe est le même : vues, contrôleurs, données-*.

Nous avons vu comment inclure un pack dans un layout de vue en utilisant javascript_pack_tag, mais comment l'inclure dans ActiveAdmin ?

Ouvrir config/initializers/active_admin.rband ajoutez ce qui suit:

config/initializers/active_admin.rb

C'est tout pour la partie configuration !
Voici un exemple de base pour l'utiliser dans un formulaire :

Exemple de base
comment l'utiliser dans un formulaire

Une chose que vous pourriez remarquer est que vous devez redémarrer votre serveur Rails pour que toute modification du contrôleur soit prise en compte. Ceci est dû au fait que la compilation de webpack n'est effectuée qu'une seule fois, au démarrage de l'application.

Une façon de corriger cela est de supprimer les lignes ajoutées à config/initializers/active_admin.rb et simplement ajouter script src: asset_pack_path('application.js') à chaque formulaire ActiveAdmin qui utilise un contrôleur StimulusJS :

Ajouter le script src: asset_pack_path('application.js')


Clonez ce dépôt Github et commencez à jouer avec StimulusJS !

Merci d'avoir lu!

Partager
Younes Serraj
Younes Serraj23 oct. 2018

Blog de Capsens

Capsens est une agence spécialisée dans le développement de solutions fintech. Nous aimons les startups, la méthodologie scrum, le Ruby et le React.

Ruby Biscuit

La newsletter française des développeurs Ruby on Rails.
Retrouve du contenu similaire gratuitement tous les mois dans ta boîte mail !
S'inscrire