Webpack en production (2/3)
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.