Ravidhu Dissanayake

Comment configurer Webpack

Webpack est un bundler, c’est à dire qu’il prend les différents modules NodeJS ainsi que les plugins JavaScript utilisés dans votre projet et crée un fichier ( ou plusieurs ) en sortie. Il permet ainsi d’utiliser l’ES6, la nouvelle version du langage JavaScript, mais également ReactJS et d’autres frameworks JavaScript. Il peut être utilisé comme compilateur et est même obligatoire pour certains frameworks JavaScript comme je le disais dans mon précédent article.
Par ailleurs, il existe un très bon chapitre dans le livre dédié à Webpack de la série SurviveJS et accessible gratuitement en ligne qui le compare à d’autres outils.

Cet outil s’utilise de plusieurs manières, avec sa mise en place, voici ce que le développeur pourra faire simplement :
  • Pour la mise en production :
    • Compiler une version optimisée pour le déploiement en production.
  • Pendant le développement :
    • Compiler l’ensemble des fichiers et avoir une version lui permettant de déboguer facilement.
    • Compiler l’ensemble des fichiers et avoir une version lui permettant de déboguer facilement et de recompiler à chaque modification faite sur les fichiers.
    • Lancer le serveur de développement de Webpack qui fait la même chose que le précédent point mais charge les fichiers compilés à partir de la mémoire et les distribuent à travers un serveur. Il recharge la page automatiquement également.

Installation de Webpack

Évidemment, Il faut installer au préalable NodeJS et NPM. Ensuite, il suffit de se placer dans le dossier du projet contenant le package.json. Enfin, dans un Terminal :

Vous pouvez rajouter « -g » pour l’installer de manière globale mais je préfère avoir une bonne séparation des modules NodeJS pour chaque projet.
Ensuite, Il faut créer le fichier webpack.dev.config.js et le fichier webpack.prod.config.js  qui vont contenir les configurations pour chaque environnement.
Remarque : Par défaut Webpack va chercher un fichier « webpack.config.js » mais nous allons mettre en place un fichier pour l’environnement de développement et un autre pour créer les fichiers de production.
Pour le moment on va remplir uniquement webpack.dev.config.js :

Comme Webpack n’est pas installé de manière globale, il faut le lancer à partir du dossier node_modules :

Néanmoins, pour faciliter le lancement des commandes on va renseigner le fichier package.json pour pouvoir lancer les commandes avec « npm run« . En somme, voici les commandes pour chaque situation :

Les fichiers d’entrées et de sorties

Commençons d’abord par définir les fichiers d’entrées et de sorties. Considérons cet exemple :

Ainsi , l’objet « entry » contient les chunks qui vont être analysés et traités. Dans l’exemple ci-dessus, Webpack va lire le fichier main.js, transformer tous les appels utilisant la syntaxe ES6 dans un format ES5 et construire un fichier concaténé contenant l’ensemble des éléments requis.
De plus, la valeur « [name].js » de « output.filename » indique que la clé de l’objet « entry » va être utilisée pour le nom du fichier généré. Ainsi, le fichier concatené va s’appeler superApp.js.
Vous pouvez forcer un nom fixe évidemment, mais je trouve que cette configuration est plus flexible.
Si vous voulez servir les fichiers à partir d’un CDN, il faut rajouter publicPath à l’objet « output » :

En effet, cette valeur va être utilisée pour savoir où sont stockés les fichiers compilés. Par ailleurs, il est également utilisé par les loaders (comme file-loader ou url-loader) afin de remplacer le début des URL. C’est pourquoi, dans l’exemple ci-dessus, « https://my.super.cdn.com/ » va être rajouté au début de tous les attributs src et href , mais aussi dans les appels url() dans les CSS.

Les plugins et les modules

La section module contient principalement la clé « loaders » avec une liste d’objets. Ces objets contiennent :

  • Le test qui permet de filtrer les fichiers.
  • Les fichiers et dossiers exclus.
  • Le loader qui va transformer le fichier.

Les loaders doivent être ajoutés avec NPM, ainsi pour babel :

Le loader BabelJS va transpiler le code ES6 vers du code ES5. Considérons donc un fichier contenant le code suivant :

Il va être importé dans le fichier main.js de la manière suivante :

On ajoute la configuration de BabelJS dans notre fichier de configuration de Webpack :

La clé « query » contient des paramètres pour BabelJS. Les « presets » permettent de donner des indications sur la syntaxe du fichier source afin de configurer BabelJS pour la transformation du code ES6 vers ES5. Le plugin pour BabelJS, « transform-runtime« , permet d’accélérer la compilation en optimisant les appels des modules.

Les plugins que je conseils

CommonChunkPlugin

Ce plugin peut être utilisé de deux façons :

  • En indiquant le chunck contenant les modules communs.
  • En indiquant le nom du fichier qui va contenir l’ensemble des modules communs à tous les chunks de votre application.

On va donc avoir des fichiers de chunk plus légers et permettre de mettre en cache chez l’utilisateur, le fichier JavaScript contenant les modules communs à toute l’application.
Pour que ces modules communs soient mis automatiquement dans un fichier à part, vous n’avez qu’a rajouter le plugin dans la liste des plugins de la manière suivante :

ou en choisissant explicitement les chunks ayant les modules communs:

Il faut bien faire attention à charger le fichier généré par le plugin avant les chunks. Pour de plus amples informations concernant la configuration de ce plugin très puissant, c’est par ici.

ExtractTextPlugin

Il requiert une installation :

Il permet de mettre dans un fichier css l’ensemble des styles écrits en SCSS ou SASS ou avec n’importe quelle autre langue de stylisation compilée.
D’abord, il faut l’ajouter dans la liste des plugins :

puis dans les modules, il faut le spécifier en tant que loader :

Vous remarquerez que j’utilise plusieurs loader. Il faut évidement les installer avant de pouvoir les utiliser. Ainsi, resolve-url, par exemple, est très utile pour réécrire les chemins d’accès des fichiers appelé avec url() dans les styles écrits en SASS .

ProvidePlugin

Il permet de spécifier un module pour une variable. En effet, lors de la compilation, la variable en clé va être détectée et le compilateur va rajouter le module spécifié en valeur. Il faut rajouter l’instantiation dans la liste des plugins. Exemple :

UglifyJsPlugin

Il sera utilisé en production principalement. En effet, il va permettre de minifier et d’obfusquer les chunks, exemple :

DefinePlugin

Il permet de définir des constantes qui seront utilisées pendant la compilation. Exemple :

NoErrorsPlugins

Il permet d’arrêter la compilation lorsqu’il y a une erreur.

La configuration pour le développement

Commençons par installer le serveur de développement :

Il faut penser à rajouter la clé « devtool » pour avoir les source-maps des fichiers compilés et un publicPath pointant sur une IP local. Donc, si on prend le fichier de configuration ci-dessus, il faut rajouter les indications suivantes pour avoir le serveur correctement configuré:

Pour commencer, la clé contentBase de l’objet devServer correspond au dossier où se trouve vos fichiers statiques (comme les images). Ensuite, en ce qui concerne les fichiers compilés, ils sont chargés en mémoire et servies par le chemin indiqué par « output.publicPath ». Ainsi, à chaque modification de fichier, les fichiers en mémoire sont remplacés et le navigateur est rechargé.
Enfin, J’ai rajouté quelques configurations :

  • Quelque plugins à titre d’exemple ( si vous utilisez CommonsChunkPlugin, il faut faire attention à charger le fichier commons.js avant les autres chunks ).
  • La clé headers pour éviter l’erreur CORS lors de l’appel au serveur.
  • La clé watchOption doit être mis en place lorsque vous utilisez Webpack dans une VM.

Remarque:
La configuration du serveur de développement doit avoir le host et le port identique au output.publicPath. En effet cela permet au fichier static de correctement charger.

Exemple d’une configuration pour l’environnement de production

La configuration de production ressemble évidemment à celle pour le développement. Il faut néanmoins rajouter quelque plugins et enlever les clés concernant les outils de développement :

 
Vous pouvez encore rajouter d’autre plugins comme OccurenceOrderPlugin ou DedupePlugin. Mais comme indiqué dans le titre, la configuration ci-dessus n’est qu’un exemple, il n’est pas prévu pour un véritable environnement de production. Mais je pense qu’il vous donne déjà une bonne direction. De plus, je vous invite à tester les différents plugins disponible sur la documentation officielle pour trouver la configuration qui convient le mieux à votre application.

Dans quel projet utiliser Webpack ?

Cet outil devrait s’intégrer dans n’importe quel type de projet qui utilise du JavaScript et du CSS. Il a un écosystème de plugin et de loader tellement large que vous allez forcément trouver chaussure à votre pied. En plus il va vous permettre d’utiliser les dernières innovations tant au niveau du langage JavaScript avec l’ECMAScript 6 aka ES6 ou le TypeScript qu’au niveau du langage CSS avec SASS ou LESS.
Il s’intègre naturellement dans des projets NodeJS mais sa flexibilité est telle qu’il est aussi l’aise dans des projets PHP avec Zend ou Symfony. En effet, pour se dernier, vous pouvez le mettre en place pour l’utiliser avec ou en remplacement d’Assetic.
En somme, Webpack vous permet d’utiliser les dernières technologies disponibles en JavaScript et en CSS, tout en vous permettant d’industrialiser vos déploiements avec facilité et flexibilité.

Leave a Comment