La gem import-maps nous permet (enfin) de nous débarrasser du tooling JS sur nos projets Ruby on Rails, que ce soit esbuild ou webpacker.

Voyons ensemble comment convertir un projet utilisant esbuild, dans mon cas, vers les import-maps.

État initial

Notre layout lie les fichiers application.js et application.css.

# views/layouts/application.html.erb
<head>
  <!-- ... -->
  <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
  <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
</head>

Le fichier CSS importe les styles provenant de divers packages NPM situés dans le répertoire node_modules ainsi qui des directives TailwindCSS.

@import "notyf/notyf.min";
@import "trix/dist/trix";
@import "actiontext.css";
@tailwind base;
@tailwind components;
@tailwind utilities;

Et le fichier JS importe différents packages ainsi que nos controllers Stimulus.

import "@hotwired/turbo-rails";
import "trix";
import "@rails/actiontext";
import "./controllers";

Un setup on ne peut plus classique.

Installation d’import-map

Si votre app n’a pas été créée avec Rails 7+, lancez les commandes ci-dessous pour installer la gem.

$ bundle add importmap-rails

Puis :

$ bundle exec rails importmap:install

Vous trouverez le nouveau fichier importmap.rb dans le répertoire config, qui remplace en quelque sorte le fichier package.json qui lisait nos dépendences NPM.

Vous y trouverez une liste de pins.

On peut charger les packages depuis plusieurs sources :

  • Une URL : pin "notyf", to: "https://ga.jspm.io/npm:notyf@3.10.0/notyf.es.js"
  • Une gem : pin "@hotwired/turbo-rails", to: "turbo.min.js"
  • Un fichier local : pin "application"
  • Un répertoire local : pin_all_from "app/javascript/controllers", under: "controllers"

Mise à jour

L’installation d’import-map vous à d’ores et déjà prérempli le fichier importmap.rb.

Vous devriez y trouver le pin @hotwired/stimulus-loading qui est une nouvelle méthode de chargement pour les controllers Stimulus ne nécessitant pas de les enregistrer manuellement.

Vous pouvez maintenant pinner 🍆 vos packages NPM pour les inclure dans la liste des imports.

$ ./bin/importmap pin notyf

Cette commande ajoutera automatiquement toutes les dépendances du package notyf.

Voici la liste des pins chez moi :

# config/importmap.rb
pin "application", preload: true
pin "i18n", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/utils", under: "utils"
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actioncable", to: "https://ga.jspm.io/npm:@rails/actioncable@7.1.1/app/assets/javascripts/actioncable.esm.js"
pin "@rails/actiontext", to: "actiontext.js"
pin "notyf", to: "https://ga.jspm.io/npm:notyf@3.10.0/notyf.es.js"

Vous pouvez à présent modifier votre layout vous charger les import-maps.

# views/layouts/application.html.erb
<head>
  <!-- ... -->
  <%= stylesheet_link_tag "trix", "data-turbo-track": "reload" %>
  <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>

  <%= javascript_importmap_tags %>
</head>

On charge maintenant les fichiers CSS manuellement et un par un pour ne plus avoir un seul gros bundle et tirer parti des capacités de HTTP 2 à charger plusieurs fichiers rapidement.

Nettoyage

Vous pouvez maintenant supprimer tous les fichiers relatifs au tooling Javascript :

$ rm -rf package.json yarn.lock node_modules

Bienvenue dans un monde rationnel sans toute la complexité des outils frontend ! 🥳

Si vous souhaitez réagir à cet article ou avez besoin d’accompagnement pour mettre à jour vos applications Ruby on Rails, contactez moi sur LinkedIn, Mastodon.