Depuis que Rails (6) est livré avec Webpacker, ce dernier tend à devenir le nouveau standard pour la précompilation des ressources. RIP Sprockets.
Comme moi, vous n'êtes peut-être pas un expert de ES6 et vous hésitez donc à vous lancer. Comme moi, vous avez peut-être aussi essayé de créer un nouveau projet et de continuer à utiliser Sprockets :
$ rails new MissYouSprockets --skip-javascript --no-skip-sprockets
Résultat : Rails vous force à entrer dans un nouveau monde : votre compilation d'actifs n'est pas entièrement configurée pour utiliser Webpacker ou Sprockets. Cet article n'a pas pour but de vous aider à conserver les anciennes méthodes, je ne m'éterniserai donc pas sur ce sujet.
Cet article vous montrera étape par étape comment configurer complètement Bootstrap 4, JQuery et bonus : le rechargement à chaud des modules ❤.
Note : Comme d'habitude, vous trouverez le code source ici avec une branche pour chaque section de cet article.
Construction des fondations du projet
Au moment de la rédaction de cet article, j'ai utilisé la dernière version de Rails (6.0.3.1) et Ruby 2.6.7. Lors de la création du projet, j'ai simplement supprimé les Turbolinks car je ne suis pas familier avec eux (à vous de voir).
$ rails -v
=> Rails 6.0.3.1
# Juste pour être sûr que la version de Rails est 6.0.3.1$ rails new WebpackHowTo --skip-turbolinks
Maintenant, nous allons également ajouter un contrôleur et une action afin de pouvoir tester ce que nous allons faire.
$ cd WebpackHowTo
$ rails g controller Welcomes index
=> ... [OK]
Fournir les plugins : JQuery et Popper.js
Si nous jetons un coup d'œil à la page officielle de Bootstrap 4, nous pouvons voir que la dernière version en date est la 4.5.0 et qu'elle nécessite JQuery et Popper.js. Ajoutons-les via Yarn :
$ yarn add jquery popper.js => yarn add v1.22.4
=> [1/4] 🔍 Résolution des paquets...
=> [2/4] 🚚 Récupération des paquets...
=> [3/4] 🔗 Lier les dépendances...
=> [4/4] 🔨 Construction de nouveaux paquets...
=> succès Sauvegarde du fichier de verrouillage.
=> succès Sauvegarde de 3 nouvelles dépendances.
=> info Dépendances directes
=> ├─ bootstrap@4.5.0↩ bootstrap@4.5.0
=> ├─ jquery@3.5.1
=> └─ popper.js@1.16.0
=> info Toutes les dépendances
=> ├─ bootstrap@4.5.0
=> ├─ jquery@3.5.1
=> └─ popper.js@1.16.0
=> ✨ Fait en 3.64s.
JQuery et Popper.js seront utilisés dans toute l'application donc nous pouvons les qualifier de plugin. Nous ne voulons pas les importer dans chaque pack différent donc il y a une méthode spéciale pour cela avec Webpacker : ProvidePlugin. Cela peut être fait dans config/webpack/environment.js car cela sera pertinent indépendamment de l'environnement actuel :
# dans config/webpack/environment.jsconst { environment } = require('@rails/webpacker');const webpack = require('webpack');environment.plugins.append('Provide', new webpack.ProvidePlugin({
$ : 'jquery',
jQuery : 'jquery',
Popper : ['popper.js', 'default']
}));const config = environment.toWebpackConfig();config.resolve.alias = {
jquery : 'jquery/src/jquery' ;config.resolve.alias = {jquery : 'jquery/src/jquery' }.
};module.exports = environnement ;
Notez que la configuration précédente rend également les plugins globalement disponibles. En d'autres termes : JQuery est désormais accessible depuis la console (🙌🏽) :
Organiser vos actifs
Il est maintenant temps d'organiser notre dossier app/javascript pour garder les différents actifs séparés.
Notez que le frontend de ce projet n'est pas une application javascript telle que Vue, Angular ou ReactJs. L'organisation suivante est adaptée à un projet ordinaire avec Sass, JQuery et Images.
Voici comment j'aime organiser mes fichiers :
app/javascript/
- channels/
// [default]
- images/
// Toutes vos images ici
- js/
- site.js // équivalent de l'ancien "application.js".
- packs/
- application.js // Votre premier "pack".
- scss/
- site.scss // équivalent à l'ancien dossier "application.scss".
Bien sûr, à l'intérieur des dossiers images, js et scss, vous devez organiser vos fichiers correctement pour que le système reste évolutif.
Maintenant, configurons notre premier pack.
# dans app/javascript/packs/application.jsrequire("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")// CSS
import 'scss/site'// JS
import('js/site')// Images
const images = require.context('../images', true)
const imagePath = (name) => images(name, true)
Nous avons fait 3 changements principaux sur le fichier :
Importation du fichier "scss/site.scss".
- Il sera l'équivalent de votre fichier application.scss.
Importation du fichier "js/site.js".
- Il sera l'équivalent de votre fichier application.js.
Décommenter le code nécessaire pour le image_pack_tag
Notez que maintenant, vous devrez importer manuellement tout fichier .js ou .scss/.css dont vous aurez besoin dans le dossier correspondant. Par exemple, si vous créez un fichier variables/_colors.scss, vous devrez alors l'importer dans votre fichier site.scss :
// dans app/javascript/scss/site.scss
@import "variables/couleurs" ;
La logique est maintenant à peu près la même qu'avec Sprockets.
Enfin et surtout. Si vous archivez votre fichier de mise en page de vues. Tu verras :
<!-- app/views/layouts/application.html.erb -->
<%= stylesheet_link_tag ‘application’, média : ‘all’ %>
<%= javascript_pack_tag 'application' %>
Il existe un pack pour le javascript et une feuille de style pour le scss.
Quoi !? Mais pourquoi alors tous les actifs sont requis dans un seul fichier dans app/packs/application.js ?
Si vous archivez votre fichier config/webpacker.yml, vous verrez que extract_css est faux pour l'environnement de développement mais vrai pour l'environnement de production. Si vous continuez et essayez de supprimer l'assistant stylesheet_link_tag et redémarrez votre serveur, vous verrez que vos ressources scss sont toujours chargées normalement. D'un autre côté, si vous changez extract_css en false et redémarrez votre serveur, vous n'aurez plus de style. Comment le réparer ?
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<tête>
<%= stylesheet_pack_tag ‘application’, média : ‘all’ %>
<%= javascript_pack_tag 'application' %>
</head>
[...]
Changez simplement l'assistant stylesheet_link_tag en assistant stylesheet_pack_tag. Ensuite, vous verrez que votre style est de retour. Lorsque extract_css est vrai, Rails extrait tous les fichiers de style (.css, .scss, etc.) dans un fichier séparé grâce au plugin mini-css-extract.
Alors à quoi bon avoir une configuration différente entre les environnements ? Attends Bobby. C'est la section suivante.
Module de rechargement à chaud Webpacker
Rails 6 et Webpacker fournissent désormais un module de rechargement à chaud prêt à l'emploi. Cela signifie que chaque fois que vous persistez un changement dans un fichier javascript de feuille de style de votre application, la page se rechargera dans votre navigateur.
Génial non ? Cela vous fera économiser beaucoup de cmd + R. 🎉
Comment mettre cela en place ? Facile, il suffit d'aller dans votre terminal, d'ouvrir un nouvel onglet dans votre répertoire de projet et de lancer la commande suivante :
$ bin/webpack-dev-server
Maintenant, si vous vous dirigez vers votre fichier site.scss par exemple et si vous apportez des modifications, vous verrez que votre navigateur se recharge automatiquement. ✔
Vouloir plus ? Cet article d'Alessandro Rodi vous explique comment paramétrer le HMR (Hot Module Reloading). Il est important d'éviter le rechargement d'une page entière lorsque vous travaillez sur un très gros projet. Lorsqu'il est correctement configuré, vous ne pouvez recompiler que les feuilles de style touchées, ce qui accélérera considérablement le rechargement de la page.
Ajout de Bootstrap
Maintenant de retour sur les rails. Ajoutons Bootstrap via Yarn :
$ fil ajouter bootstrap
=> fil ajouter v1.22.4
=> [1/4] 🔍 Résolution des packages…
=> [2/4] 🚚 Récupération des packages…
=> [3/4] 🔗 Lier les dépendances…
=> [4/4] 🔨 Construire de nouveaux packages…
=> succès Fichier de verrouillage enregistré.
=> succès Enregistré 1 nouvelle dépendance.
=> info Dépendances directes
=> bootstrap@4.5.0
=> info Toutes les dépendances
=> bootstrap@4.5.0
=> ✨ Fait en 4.03s.
Nous devons maintenant exiger à la fois ses fichiers js et scss. Rendez-vous dans notre dossier app/javascript/.
D'abord le fichier js :
// dans app/javascript/js/
importer 'bootstrap'
… et le fichier scss :
// dans app/javascript/scss/
@import "~bootstrap/scss/bootstrap.scss" ;
À ce stade, votre HMR devrait avoir rechargé votre page deux fois (une pour chaque fichier). La deuxième fois, vous avez dû remarquer que la police par défaut de votre application est passée à System-ui (la police par défaut de Bootstrap 4). Cela signifie que Bootstrap est prêt à fonctionner.
Si vous n'aimez pas le dossier javascript…
Webpacker définit par défaut l'emplacement source_path des actifs sur app/javascript. Peut-être que je suis de la vieille école, mais voir un dossier javascript (sans "s") me rend grincheux.
J'aime le renommer webpacker :
# dans config/webpacker.yml
par défaut : &par défaut
source_path : app/webpacker # au lieu de "app/javascript"
source_entry_path : packs
public_root_path : public
public_output_path : packs
chemin_cache : tmp/cache/webpacker
N'oubliez pas de redémarrer votre webpack-dev-server après.
Et voilà ! 👌
PS : Merci à Kernael qui m'a aidé pour la partie fourniture des plugins.