• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Retour sur l’ElixirConf EU 2021
Retour sur l’ElixirConf EU 2021
1 mai 2021
Ouidou accélère sa croissance en ouvrant une nouvelle agence à Lyon !
Ouidou accélère sa croissance en ouvrant une nouvelle agence à Lyon !
10 mai 2021
Ressources > Articles techniques > Webpacker : the highway to hell

Webpacker : the highway to hell

Article écrit par Martin Catty

Un outil pour les gouverner tous

Note I : dans cet article quand je parle de production il s’agit du mode production plutôt que d’environnement de production.

Note II : Webpacker est une gem permettant d’utiliser Webpack dans une application Ruby.

Note III : Juste parce que j’aime bien les chiffres romains.

Nos applications Rails, dès lors qu’elles quittent nos machines, tournent toujours dans un mode production, aussi bien sur un environnement de pré-production que de revue.

Lorsque nous démarrons de nouveaux projets, nous utilisons notre générateur de projets, répondant au doux nom d’Opsible (car utilisant Ansible) et qui nous permet de mettre en place une application prête à l’emploi, aussi bien localement qu’en production.

Tous nos projets utilisant Docker, l’outil est en charge de mettre en place une configuration fonctionnelle.

Il s’appuie également sur des templates Rails pour nous permettre de créer de pures API ou des monolithes.

Lors d’une nouvelle mise à jour d’Opsible s’est reposée la sempiternelle question : Sprockets et/ou Webpacker ?

Sprockets et/ou Webpacker ?

Si vous lisez le guide Ruby on Rails dédié à Webpacker la réponse est très claire (</troll>) : vous pouvez utiliser les deux pour faire … les mêmes choses.

New Rails apps are configured to use webpack for JavaScript and Sprockets for CSS, although you can do CSS in webpack.

Dans l’équipe notre consensus était clair : Webpack a plutôt vocation à être utilisé lorsqu’on intègre des app riches dans notre monolithe.

Comprenez que dès que l’on souhaite intégrer des frameworks front type Vue.js nous mettons en place Webpacker.

Sauf que celui-ci venait en addition de Sprockets plutôt qu’en remplacement.

Qui peut le plus peut le moins

Dès lors qu’on bascule dans ce setup qui mix les deux approches, ceux qui travaillent sur des parties sans Webpack ont un peu l’impression de se faire avoir.

Ils font tourner les processus nécessaires à Webpacker, notamment un serveur dédié à la recompilation des assets, sans en profiter.

En effet, Webpack offre des avantages non négligeables comme le hot reloading et le hot module replacement, offrant une expérience de développement bien plus fluide.

Dès lors, nous avons décidé pour nos nouveaux projets de ne garder que Webpacker.

De la bonne configuration de Webpacker

Avec Webpacker la règle est simple : tant que vous n’êtes pas en production vous n’êtes pas sûr que ça fonctionne.

Là où Rails nous a habitué à son convention over configuration, dans le contexte de Webpack il semble n’y avoir étonnamment pas de consensus fort sur la bonne façon d’organiser ses fichiers, quand l’utiliser, etc.

Pour matérialiser les soucis qu’on peut rencontrer lors de sa mise en place je vais prendre un cas d’usage dans l’air du temps : l’intégration de Tailwind dans notre application.

La configuration de Webpacker (config/webpacker.yml) est découpée en environnements, vous aurez donc probablement une configuration development et une production à minima (nous y reviendrons).

Notre objectif est de ne garder dans notre layout que les deux balises suivantes :

= stylesheet_pack_tag  "application", media: "all", "data-turbolinks-track": "reload" = javascript_pack_tag  "application", "data-turbolinks-track": "reload" 

Notre configuration par défaut de Webpacker est la suivante :

default: &default   source_path: app/javascript   source_entry_path: packs   public_root_path: public   public_output_path: packs   cache_path: tmp/cache/webpacker   webpack_compile_output: true   check_yarn_integrity: false   … 

Rien de complexe ici, par défaut nos fichiers seront recherchés dans app/javascript. Les « manifestes » devront se trouver dans le dossier packs. Les dossiers de sortie des fichiers compilés seront dans public/packs.

Sans perdre de temps nous voilà en route pour intégrer Tailwind. L’un des avantages de Webpacker est de pouvoir facilement intégrer des bibliothèques publiées sous forme de paquets NPM.

Ni une ni deux :

yarn add tailwindcss yarn tailwind init 

Puis on configure notre fichier postcss.config.js :

module.exports = {   plugins: [     require("postcss-import"),     require("tailwindcss"), // on ajoute cette ligne uniquement     require("postcss-flexbugs-fixes"),     require("postcss-preset-env")({       autoprefixer: {         flexbox: "no-2009"       },       stage: 3     })   ] }; 

On part sur une arborescence de la sorte pour organiser notre JavaScript :

app/javascript ├── channels │   ├── consumer.js │   └── index.js └── packs     └── application.js 

Et celle ci pour nos CSS :

app/stylesheet └── app.scss 

Dans notre manifeste application.js on va référencer nos fichiers CSS, c’est une pratique normale de Webpack qui fonctionne sur un mécanisme d’import.

Dès lors que les fichiers CSS ont été référencés, ils sont utilisables dans notre application et cela fonctionne même sans directive d’import de notre manifeste CSS dans notre layout.

import Rails from "@rails/ujs"; import Turbolinks from "turbolinks"; import * as ActiveStorage from "@rails/activestorage"; import "channels";  import "../../stylesheet/app.scss"; // on ajoute cette ligne  Rails.start(); Turbolinks.start(); ActiveStorage.start(); 

Le torse bombé on relance notre serveur webpack et là, c’est le drame.

Erreur postcss 8

Visiblement Tailwind veut la version 8 de PostCSS. Mais cette version n’est pas compatible avec la version stable actuelle de Webpacker (5.3).

Combatif, on ne lâche pas l’affaire, il se trouve qu’il y a une version de Tailwind compatible avec PostCSS 7.

yarn remove tailwindcss yarn add tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9 

Magnifique, on peut maintenant écrire des styles dans notre fichier app/stylesheet/app.scss, ceux-ci seront appliqués à la volée.

Profitons-en pour importer également Tailwind (qui n’est pas encore chargé à ce stade), on aura au final dans notre fichier app.scss :

@import "tailwindcss/base"; @import "tailwindcss/utilities"; @import "tailwindcss/components"; 

Cela fonctionne bien, avec un bémol :

webpack_1  | ℹ 「wdm」: Compiled successfully. webpack_1  | ℹ 「wdm」: Compiling... webpack_1  | ℹ 「wdm」: Hash: e0f5684b0fd5ecd26488 webpack_1  | Version: webpack 4.46.0 webpack_1  | Time: 4470ms 

Quasiment 5 secondes de compilation, et ce à chaque fois qu’on va introduire une directive dans le fichier. Cela tient au fait que Tailwind contient une tétrachiée de classes utilitaires, prêtes à l’emploi et mises à disposition même si on ne s’en sert pas.

Pour y palier on va découper notre fichier en deux :

app/stylesheet ├── app.scss └── tailwind.scss 

Le nouveau fichier tailwind.scss ne contiendra que les directives relatives à ce dernier. Lorsqu’on édite notre fichier app.scss, on revient à des temps acceptables :

webpack_1  | ℹ 「wdm」: Compiled successfully. webpack_1  | ℹ 「wdm」: Compiling... webpack_1  | ℹ 「wdm」: Hash: 9f7a514f5e27f38ab57e webpack_1  | Version: webpack 4.46.0 webpack_1  | Time: 156ms 

Maintenant que tout est en ordre il faut qu’on prépare notre configuration pour la production. Si la balise suivante est inutile en local, elle le sera en production :

= stylesheet_pack_tag  "application", media: "all", "data-turbolinks-track": "reload" 

On va donc créer notre manifeste :

app/javascript/packs ├── application.js └── application.scss 

Qui contient les même instructions :

@import "../../stylesheet/tailwind.scss"; @import "../../stylesheet/app.scss"; 

On rajoute quelques directives dans notre fichier app.scss et là surprise, notre build prend de nouveau 5 secondes !

webpack_1  | ℹ 「wdm」: Compiling... webpack_1  | ℹ 「wdm」: Hash: 36fdd1b07e74458fd268 webpack_1  | Version: webpack 4.46.0 webpack_1  | Time: 4754ms webpack_1  | Built at: 04/27/2021 2:35:27 PM 

Et oui dès lors que notre manifeste est déclaré, l’ensemble des fichiers qui y sont référencés vont être surveillés et compilés.

Pour éviter cela nous avons décidé de déclarer le manifeste dans un dossier qui ne sera utilisé que pour la production.

production:   <<: *default    additional_paths: ["app/stylesheet"] 
app/stylesheet ├── app.scss ├── packs │   └── application.scss └── tailwind.scss 

S’en est tout de mes pérégrinations dans le pays merveilleux de Webpack(er). Je vous ai toutefois laissé avec un problème à résoudre, celui de retirer les CSS inutilisées dans votre build de production (autrement le fichier Tailwind pèse quelque 3Mo non compressé).

Si vous avez des avis / astuces / bonnes pratiques sur la façon de dompter ce monstre qu’est Webpack, n’hésitez pas à engager la conversation sur Twitter.

À lire aussi

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique

Lire la suite

intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 

Lire la suite

Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 

Lire la suite

image miniature les nouveautés Atlassian
26 février 2025

Les nouveautés Atlassian en 2025

Lire la suite

Articles associés

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite
intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 


Lire la suite
Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter