Makina Blog
Surcharge thématique avec Webpack
Utiliser un loader pour surcharger à la volée des éléments de thème d'un projet Webpack.
Notre objectif
Imaginons un développement frontend proposant un certain nombre de fonctionnalités intéressantes. Une partie de son implémentation correspond à son thème graphique.
Nous souhaitons ré-utiliser ce développement, les fonctionnalités restant les mêmes, mais le thème en revanche doit être différent.
Les loaders Webpack
Les loaders Webpack sont des outils de transformation que Webpack appelle en fonction du type de ressources qu'il lit (par exemple, il va appeler le loader Sass pour transformer un fichier Sass en CSS).
Ils peuvent être chaînés (enfin de réaliser plusieurs transformations les unes à la suite des autres).
Et on peut écrire facilement ses propres loaders…
Écrire un loader
La structure d'un loader est très simple. C'est une fonction qui reçoit un contenu en entrée et qui doit renvoyer le contenu transformé:
module.exports = function(content) { this.cacheable && this.cacheable(); return "<!-- contenu interdit -->"; };
On l'utilise en le déclarant dans notre webpack.config.js:
module.exports = { ... module: { loaders: [{ test: /\.(html)$/, loader: "my-loader" }], ...
Dans cet exemple, nous avons construit un loader un petit peu radical (tous les fichiers .html sont remplacés par un commentaire mentionnant que le contenu est interdit).
Note: ici nous avons mis notre loader dans la section "loaders", mais il existe aussi les sections "preLoaders" et "postLoaders" qui, comme leurs noms l'indiquent, se déclenchent avant ou après la section "loaders".
Passer des paramètres au loader
Le loader peut accepter des paramètres en querystring. Par exemple, on peut l'appeler comme ceci:
loader: "my-loader?color=pink"
Et dans l'implémentation du loader on peut récupérer la valeur du paramètre "color" ainsi:
var loaderUtils = require("loader-utils"); module.exports = function(content) { ... loaderUtils.parseQuery(this.query).color;
Pitch
Pour travailler en asynchrone il y a plusieurs approches. Une des plus simples est d'utiliser la fonction "pitch". Elle nous permet de mettre dans une variable "data" des informations qui seront exploitables dans la fonction principale. Exemple:
module.exports = function(content) { return content + data.additionnal_part; }; module.exports.pitch = function(remainingRequest, precedingRequest, data) { fs.readFile('./additional.txt', 'utf8', function (err, txt) { if(!err) { data.additionnal_part = txt; } }); };
Un loader pour surcharger le thème
Avec ces outils nous pouvons maintenant construire notre loader de surcharge thématique.
Nous avons donc créé un certain nombre de composants, chacun faisant des "require" vers des fichiers HTML ou CSS implémentant le thème. Et nous souhaitons maintenant remplacer ces fichiers à la volée lors du build par une version custom fournie dans un dossier spécifique.
Tout d'abord, pour agir sur les fichier css ou html, voici la config Webpack qu'il nous faut:
module: { ... preLoaders: [{ test: /\.(html|css)$/, loader: "theme-preloader?themepath=../customtheme" }],
Concernant l'implémentation, nous allons lire le paramètre "themepath" pour connaître le chemin du dossier fournissant le thème custom, et la fonction "pitch" va aller lire le fichier attendu s'il existe:
var fs = require('fs') var loaderUtils = require("loader-utils"); var request = require('request'); module.exports = function(content) { this.cacheable && this.cacheable(); return this.data.override || content; }; module.exports.pitch = function(remainingRequest, precedingRequest, data) { this.cacheable && this.cacheable(); var query = loaderUtils.parseQuery(this.query); var path = this.resourcePath var src_root = path.substring(0, path.lastIndexOf('/src/') + 1) var resource_path = path.substring(path.lastIndexOf('/src/') + 4); var newpath = src_root + query.themepath + resource_path; fs.readFile(newpath, 'utf8', function (err, newcontent) { if(!err) { console.log("OVERRIDE " + path + " WITH " + newpath); data.override = newcontent; } }); }
Et voilà !
Formations associées
Formations Front end
Formation Développement d'applications JavaScript
À distance (FOAD) Du 2 au 4 avril 2025
Voir la Formation Développement d'applications JavaScriptFormations SIG / Cartographie
Formation Leaflet
Toulouse Du 1 au 2 juillet 2025
Voir la Formation LeafletActualités en lien
Générer un fichier PMTiles avec Tippecanoe
SIG
28/02/2024

Publier une documentation VitePress sur Read The Docs
Logiciel libre
01/02/2024

Créer une application en tant que composant web avec Stencil
Application Web & Mobile
04/04/2023
