Webpack en production (2/3)

Eric Burel
PointJS
Published in
5 min readNov 19, 2019

--

Les outils — Épisode 3

Ceci est le deuxième épisode de notre série sur Webpack. Pour découvrir les bases, rendez-vous à l’épisode 1. Pour mettre en place un serveur de développement, rendez-vous à l’épisode 3.

Une config pour le dev, une config pour la prod

Les besoins en mode développement et en production sont parfois contradictoires. Par exemple, les commentaires générés par Webpack sont pratiques lorsque l’on veut visualiser le graphe de dépendance des modules, mais alourdissent le fichier lors de sa mise en ligne.

La solution est simple : construisons deux (et même trois) configurations différentes : une pour la production, une pour le développement, et une pour les parties communes.

Une config de développement

Copier le fichier webpack.config.js pour créer un nouveau fichier webpack.config.dev.js. Il n'y a pas de règle pour ce nom, mais ce format est le plus courant. Si vous n’avez pas de webpack.config.js , rendez-vous à l’épisode 1 de notre série sur Webpack.

On va enfin pouvoir se défouler, et utiliser tous les outils qui nous permettent de développer plus vite et dans de meilleures conditions.

Créer le bundle dans un dossier à part entière

Première étape, on va créer notre bundle.js dans un dossier à part entière, pour séparer les sources des fichiers construits automatiquement. Dans votre configuration, il faut ajouter les éléments suivants :

var path = require('path');

...
output: {
filename: 'bundle.js',
// dossier dans lequel le bundle sera créé
path: path.resolve(__dirname, 'dist')
},

path est un module node permettant de gérer les chemins des fichiers et des dossiers, __dirname est ce que l'on appelle une variable magique, elle correspond au dossier dans lequel se situe le fichier courant (ici notre webpack.config.dev.js). La plupart des langages de programmation ont des concepts similaires.

Pensez au passage à déplacer le fichier index.html qui utilise votre code dans le dossier dist. Cela sera utile par la suite, lors de la mise en place d'un serveur de développement par exemple.

Lorsque vous serez à l’aise avec Webpack, vous pourrez installer le plugin HtmlWebpackPlugin pour gérer ce fichier index.html de façon plus propre.

Configurer les source maps

Si vous ouvrez la console du navigateur, vous allez voir apparaître deux valeurs, résultats des console.log de nos fichiers d'exemples.

Vous pouvez accéder à la source, mais ça va être un peu moche, car la source n’est pas votre beau fichier .js mais l'énorme bundle.js construit par Webpack.

Les source maps permettent de faire le lien entre chaque ligne du bundle et le fichier d’origine. La navigateur pourra alors vous afficher la source d’origine, ce qui facilite le débogage. Dans la config :

devtool: 'inline-source-map',​

Si vous rebuildez l’application, vous allez désormais pouvoir retrouver la vraie source dans la console :

webpack --config webpack.config.dev.js

Et une config pour la prod

Toujours à partir du fichier webpack.config.js, créez un nouveau fichier webpack.config.prod.js. Vous pouvez d'ores et déjà le configurer pour que le bundle soit créé dans le dossier build (même manipulation que pour la config de développement, on change juste le nom du dossier).

Minifier les fichiers

Première étape, supprimons les commentaires générés par Webpack et minifions notre fichier .js. La minification consiste simplement à compresser un fichier en éliminant les choses inutiles (commentaires) et en raccourcissant le nom de variables. var foobar = 42 devient var a = 42. Cela paraît idiot, mais on gagne à la longue énormément de place dans notre fichier. C’est important car le navigateur de l’utilisateur final devra télécharger ce fichier.

Utilisons le plugin UglifyjsWebpack, référence dans le domaine. Le nom uglify vient du fait que le code minifié est généralement...très moche (pas d'espaces, noms de variables en une lettre, etc.).

npm i --save-dev uglifyjs-webpack-pluginvar UglifyJsPlugin = require('uglifyjs-webpack-plugin')
...
plugins:[
new UglifyJsPlugin()
]

Pourquoi un plugin et pas un loader ? Parce que les loaders ne fonctionnent que lors de l’import d’un fichier dans un autre. Pour toutes les opérations globales, qui ne dépendent pas d’un fichier précis, comme par exemple ici la minification du bundle, on passera plutôt par un plugin.

Vous pouvez tester votre config, vous allez constater que le fichier bundle.js est désormais bien plus léger : 6.58kb contre 52.2kb dans le code d'exemple.

webpack --config webpack.prod.js

Webpack met cependant beaucoup plus de temps à construire son bundle, mais ce n’est pas un problème en production, car les builds ne sont pas fréquents.

Alléger les source maps

Les besoins en source maps ne sont pas non plus les mêmes en développement et en production, même s’il est souhaitable d’en garder un minimum.

Changez la configuration comme suit :

devtool:'source-map',
plugins:[
new UglifyJsPlugin({
sourceMap: true
})
]

Notez que l’on précise aussi au module de minification de ne pas supprimer les source maps.

Un environnement adapté

Les outils Node reposent sur l’utilisation de variables d’environnement pour différencier le mode développement du mode production. L’environnement par défaut est celui de développement, il faut donc modifier notre configuration pour signaler aux plugins et aux loaders que nous sommes ici en production.

var webpack = require('webpack')
...
plugins:[
...,
new webpack.DefinePlugin({
'process.env.NODE_ENV': 'production'
})
]

Le DefinePlugin permet de gérer les variables globales, ici process.env.NODE_ENV (l'objet global process.env contient toutes les variables d'environnement).

webpack-merge pour les points communs

Comme tout bon développeur, vous n’aimez pas écrire les choses deux fois. Nos deux configurations ont des points communs, alors nous pouvons les fusionner.

En bonus : pour ne pas trop alourdir ce point, je vous propose de découvrir par vous-même cet outil sur la documentation officielle.Si vous avez bien compris les points précédents, créer une configuration commune est relativement facile.

N’hésitez pas à poser vos questions en commentaires !

Voilà, vous êtes équipés pour créer des configurations Webpack pour tous vos besoins ! Le prochain point de cette série sur les outils sera encore consacré à Webpack, et son serveur de développement.

--

--

PointJS
PointJS

Published in PointJS

Du JS, en français, un point c’est tout. Une idée d’article ? Contactez-nous : pointjs@lbke.fr

Eric Burel
Eric Burel

Written by Eric Burel

Next.js teacher and course writer. Co-maintainer of the State of JavaScript survey. Follow me to learn new Next.js tricks ✨ - https://nextjspatterns.com/