Introduction
Webpack est le bundler de référence pour les applications web modernes, capable de transformer des modules ES6+, CSS, images et fonts en bundles optimisés. En 2026, avec Webpack 5, vous bénéficiez de fonctionnalités natives comme le code splitting automatique, la mise en cache persistante et une meilleure gestion des assets. Ce tutoriel intermediate vous guide pas à pas pour configurer un projet complet : du bundling basique aux optimisations production avec Hot Module Replacement (HMR).
Pourquoi Webpack ? Contrairement à Vite (plus rapide au dev mais moins flexible), Webpack excelle dans les builds complexes avec de nombreux loaders/plugins. Imaginez-le comme une chaîne d'assemblage : chaque loader traite un type de fichier (JS vers ES5, Sass vers CSS), les plugins injectent du HTML ou nettoient les dossiers. À la fin, un professionnel bookmarke ce guide pour ses setups récurrents. Prêt à bundler comme un pro ? (128 mots)
Prérequis
- Node.js 20+ installé
- Connaissances de base en JavaScript ES6+ et modules
- Un éditeur comme VS Code
- Git pour versionner le projet
Initialisation et installation
mkdir webpack-tutorial && cd webpack-tutorial
npm init -y
npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin mini-css-extract-plugin css-loader style-loader sass-loader sass babel-loader @babel/core @babel/preset-env clean-webpack-plugin
npm install lodashCette commande initialise un projet npm et installe Webpack 5, CLI, dev server, plugins essentiels (HTML, CSS extraction, nettoyage) et loaders (Babel pour JS moderne, Sass/CSS). Lodash est un module externe à bundler. Évitez d'installer globalement pour isoler les versions par projet.
Structure de fichiers de base
Créez manuellement :
src/index.js: point d'entrée JSsrc/style.scss: fichier Sasspublic/index.html: template HTML (optionnel, plugin le gère)
``
src/
index.js
style.scss
public/
index.html
webpack.config.js
package.json
`
Webpack part de src/index.js (entry) pour générer dist/main.js` (output).Configuration Webpack basique
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
mode: 'development',
devServer: {
static: './dist',
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new MiniCssExtractPlugin(),
],
module: {
rules: [
{
test: /\.scss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
};Cette config de base définit l'entry JS, output nettoyé dans /dist, mode dev avec server sur port 3000. Le HtmlWebpackPlugin injecte le bundle dans HTML ; MiniCssExtractPlugin sépare CSS en fichier distinct. Ajouté un rule Sass basique. Testez avec npx webpack serve – évitez mode: 'none' sans optimisation manuelle.
Entry point JS avec modules
import _ from 'lodash';
import './style.scss';
const greet = () => {
const element = document.createElement('div');
element.innerHTML = _.join(['Webpack', 'est', 'super!'], ' ');
element.classList.add('hello');
return element;
};
document.body.appendChild(greet());
console.log('Webpack chargé!');Ce fichier d'entrée importe Lodash (bundlé), SCSS et crée un élément DOM dynamique. Il démontre le tree-shaking (Webpack élimine le code inutilisé de Lodash). Ajoutez console.log pour vérifier en dev tools. Piège : oubliez document.body.appendChild et rien ne s'affiche.
Ajout du support Babel
Pourquoi Babel ? Pour transpiler ES6+ (async/await, optional chaining) vers ES5 compatible anciens navigateurs. Créez .babelrc ou intégrez dans webpack.config.js.
Loader Babel et preset
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
mode: 'development',
devServer: {
static: './dist',
hot: true,
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new MiniCssExtractPlugin(),
],
module: {
rules: [
{
test: /\.scss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
};Ajout du rule Babel pour .js (exclut node_modules pour perf). @babel/preset-env cible les browsers via browserslist. Activez HMR avec hot: true. Lancez npx webpack serve : modifications JS/CSS rechargent instantanément. Piège : sans exclude: /node_modules/, le build ralentit énormément.
Fichier SCSS et HTML template
$primary: #3498db;
.hello {
color: $primary;
font-family: Arial, sans-serif;
padding: 20px;
border: 2px solid $primary;
border-radius: 8px;
}Ce SCSS utilise variables et nesting, compilé en CSS par loaders chainés (sass → css → extract). Associez à public/index.html basique avec . Le plugin injecte automatiquement.
Configuration production optimisée
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
...require('./webpack.config.js'),
mode: 'production',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
optimization: {
splitChunks: {
chunks: 'all',
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
],
};Héritez de la config dev via ...require('./webpack.config.js'). Mode 'production' active Terser (minification JS) et tree-shaking. [contenthash] cache-buste les fichiers ; splitChunks sépare vendor (Lodash). Ajoutez package.json scripts : "build": "webpack --config webpack.prod.js". Build : npm run build génère assets optimisés.
Scripts npm et fichier HTML
{
"name": "webpack-tutorial",
"version": "1.0.0",
"scripts": {
"dev": "webpack serve",
"build": "webpack --config webpack.prod.js",
"build:analyze": "webpack --config webpack.prod.js --profile --json > stats.json"
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"babel-loader": "^9.1.3",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^7.1.0",
"html-webpack-plugin": "^5.6.0",
"mini-css-extract-plugin": "^2.9.0",
"sass": "^1.77.0",
"sass-loader": "^16.0.0",
"style-loader": "^4.0.0",
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.1.0"
},
"dependencies": {
"lodash": "^4.17.21"
}
}Scripts pour dev (HMR), build prod et analyse (webpack-bundle-analyzer via stats.json). Versions 2026 compatibles. Créez public/index.html : pour template.
Bonnes pratiques
- Utilisez
mode: 'production'pour minification auto et optimisations (évite configs verbeuses). - Cachez agressivement :
cache: { type: 'filesystem' }dans devServer pour rebuilds 10x plus rapides. - Code splitting :
import()dynamique pour lazy-loading (e.g., routes). - Browserslist : Configurez
.browserslistrcpour Babel cible précise (e.g., '> 0.5%, last 2 versions'). - Analysez bundles :
webpack-bundle-analyzerpour détecter vendors gonflés.
Erreurs courantes à éviter
- HMR ne marche pas : Vérifiez
hot: trueetdevServer.static: './dist'; redémarrez si port occupé. - CSS non appliqué : Chain loaders inverse (postcss → css → extract) ; testez sans MiniCss en dev avec style-loader.
- Build lent : Excluez
node_modulesde Babel ; utilisezthread-loaderpour paralléliser. - Cache pollué : Ajoutez
clean: trueou CleanWebpackPlugin ; supprimez.cache/manuellement.
Pour aller plus loin
- Documentation officielle : Webpack 5 Guide
- Avancé : Intégrez TypeScript (
ts-loader), images (file-loader), PWA (WorkboxWebpackPlugin) - Alternatives : Essayez esbuild ou Rspack pour vitesse
- Formations Learni Dev : Masterclass Webpack + Vite pour seniors