Skip to content
Learni
View all tutorials
Outils de Build

Comment configurer Webpack 5 pour un projet moderne en 2026

Introduction

Webpack 5 reste en 2026 l'outil de bundling le plus puissant pour les applications JavaScript modernes, surpassant Vite pour les projets complexes nécessitant une personnalisation fine. Contrairement aux bundlers zero-config, Webpack offre un contrôle granulaire sur le tree-shaking, le code splitting et les optimisations assets, essentiels pour des apps scalables comme celles avec micro-frontends ou PWAs.

Ce tutoriel intermédiaire vous guide pas à pas pour configurer un projet complet : transpilation ES6+ via Babel, gestion CSS/Sass, Hot Module Replacement (HMR), et builds production avec minification et chunking. Vous obtiendrez un setup fonctionnel, testé, prêt pour l'intégration CI/CD. Idéal pour les développeurs seniors gérant des monorepos ou des libs partagées, où la flexibilité prime sur la simplicité. À la fin, votre bundle sera optimisé pour Lighthouse 100/100.

Prérequis

  • Node.js 18+ installé
  • Connaissances en JavaScript ES6+, modules import/export
  • npm ou yarn comme gestionnaire de paquets
  • Éditeur de code (VS Code recommandé)
  • Terminal Unix-like (WSL sur Windows)

Initialisation du projet

terminal
mkdir webpack-modern-project
cd webpack-modern-project
npm init -y
npm install --save-dev webpack@5 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
npm install lodash

Cette commande initialise un projet npm et installe Webpack 5 avec ses outils essentiels : CLI pour les scripts, dev-server pour HMR, plugins pour HTML/CSS, loaders pour CSS/Sass/Babel, et lodash comme dépendance pour tester l'import. Évitez les versions globales pour isoler les projets.

Scripts package.json

package.json
{
  "name": "webpack-modern-project",
  "version": "1.0.0",
  "scripts": {
    "dev": "webpack serve --mode development --open",
    "build": "webpack --mode production",
    "build:analyze": "webpack --mode production --profile --json > stats.json"
  },
  "devDependencies": {
    "@babel/core": "^7.24.0",
    "@babel/preset-env": "^7.24.0",
    "babel-loader": "^9.1.3",
    "css-loader": "^7.0.0",
    "html-webpack-plugin": "^5.6.0",
    "mini-css-extract-plugin": "^2.9.0",
    "sass": "^1.77.0",
    "sass-loader": "^14.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"
  }
}

Les scripts définissent dev pour le serveur de développement avec auto-ouverture du navigateur, build pour production, et build:analyze pour l'analyse des bundles via webpack-bundle-analyzer (optionnel). Cela structure les workflows sans redondance.

Fichiers source de base

src/index.js
import _ from 'lodash';
import './styles.scss';

const message = `Webpack 5 fonctionne ! Taille lodash: ${_.size({key: 'value'})}`;

document.body.innerHTML = `<h1>${message}</h1><div class="box">Boîte stylée</div>`;

console.log('Projet prêt pour HMR');

Ce fichier d'entrée importe lodash (tree-shakable), un SCSS, et manipule le DOM. Il démontre le bundling multi-ressources. Créez aussi src/styles.scss avec .box { background: blue; padding: 20px; color: white; } pour tester.

Configuration Webpack de base

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true
  },
  devServer: {
    static: './dist',
    port: 3000,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      title: 'Webpack 5 Moderne'
    })
  ],
  mode: 'development'
};

Configuration initiale avec entry/output hashés pour cache-busting, nettoyage auto du dist, et devServer pour HMR/port 3000. HtmlWebpackPlugin injecte le bundle dans un template HTML. Créez src/index.html basique : Webpack.

Premier test en développement

Exécutez npm run dev : Webpack lance un serveur sur http://localhost:3000 avec HMR activé. Modifiez src/index.js ou SCSS : les changements s'appliquent instantanément sans reload complet, comme un "chaud" live-reload. Vérifiez la console pour confirmer lodash et les styles.

Ajout de Babel pour transpilation

.babelrc
{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "chrome": "58",
        "firefox": "57",
        "ie": "11",
        "safari": "12"
      },
      "useBuiltIns": "usage",
      "corejs": 3
    }]
  ]
}

"@babel/preset-env" transpile ES6+ vers des browsers legacy, avec polyfills on-demand via core-js. Targets définissent la compatibilité ; useBuiltIns: 'usage' optimise en important seulement les polyfills nécessaires, évitant un bundle gonflé.

Loaders Babel et CSS dans webpack.config

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    assetModuleFilename: 'assets/[hash][ext][query]',
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /\.(scss|css)$/i,
        use: [
          process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource'
      }
    ]
  },
  devServer: {
    static: './dist',
    port: 3000,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      title: 'Webpack 5 Moderne'
    }),
    ...(process.env.NODE_ENV === 'production' ? [new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css'
    })] : [])
  ],
  mode: 'development'
};

Règles loaders : Babel pour JS (exclut node_modules), CSS/Sass chain (style-loader dev, MiniCssExtract prod), asset/resource pour images (copie optimisée). Conditionnel sur NODE_ENV sépare dev/prod. Ajoutez une image dans src pour tester.

Optimisations avancées

Testez : Ajoutez du code async ES2022 dans index.js (ex: top-level await). Babel transpile, HMR persiste. Pour prod, npm run build génère dist/ avec CSS extrait, JS minifié (via TerserPlugin implicite), assets hashés.

Code splitting avec dynamic imports

src/index.js
import _ from 'lodash';
import './styles.scss';

const message = `Webpack 5 avec splitting ! Taille lodash: ${_.size({key: 'value'})}`;

document.body.innerHTML = `<h1>${message}</h1><div class="box">Cliquez pour lazy load</div><button id="load">Charger chunk</button>`;

const btn = document.getElementById('load');
btn.addEventListener('click', async () => {
  const { lazyFunc } = await import('./lazy.js');
  lazyFunc();
});

console.log('HMR prêt');

Dynamic import crée un chunk séparé pour ./lazy.js (créez-le : export const lazyFunc = () => alert('Chunk chargé !');). Webpack split auto, prefetch/preload optionnels via magic comments. Idéal pour lazy-loading routes.

Configuration finale avec splitting et perf

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: {
    main: './src/index.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].chunk.js',
    assetModuleFilename: 'assets/[hash][ext][query]',
    clean: true
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\\/]node_modules[\\\/]/,
          name: 'vendors',
          chunks: 'all',
          priority: 20
        }
      }
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /\.(scss|css)$/i,
        use: [
          process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
          {
            loader: 'css-loader',
            options: { importLoaders: 1 }
          },
          'sass-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'assets/[hash][ext][query]'
        }
      }
    ]
  },
  devServer: {
    static: './dist',
    port: 3000,
    hot: true,
    open: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      title: 'Webpack 5 Moderne'
    }),
    ...(process.env.NODE_ENV === 'production' ? [
      new MiniCssExtractPlugin({
        filename: '[name].[contenthash].css'
      })
    ] : [])
  ],
  mode: process.env.NODE_ENV || 'development'
};

Optimisation splitChunks extrait vendors (lodash) en chunk partagé. ChunkFilename pour dynamic imports. CSS-loader importLoaders:1 applique Sass à @import. Perf : bundles <100kb gzippés, cache via hash.

Bonnes pratiques

  • Séparez dev/prod : Utilisez process.env.NODE_ENV pour conditionner loaders/plugins, minimisant le bundle dev.
  • Tree-shaking : Importez nommément (ex: import { debounce } from 'lodash'), et activez sideEffects: false dans package.json.
  • Cache agressif : Hashes sur tous outputs + cache: { type: 'filesystem' } dans webpack.config pour builds 10x plus rapides.
  • Analyse bundles : Ajoutez webpack-bundle-analyzer pour visualiser tailles/chunks.
  • Source maps : devtool: 'source-map' en dev, 'hidden-source-map' en prod.

Erreurs courantes à éviter

  • Pas d'exclude node_modules sur babel-loader : bundle explose (GoT 10s+).
  • Oubli clean: true : Fichiers orphelins polluent dist/ après rebuilds.
  • Style-loader en prod : CSS inline gonfle JS ; utilisez toujours MiniCssExtractPlugin.
  • Pas de splitChunks : Vendors dupliqués dans chaque chunk, +200kb/app.

Pour aller plus loin

  • Documentation officielle : Webpack 5 Guide
  • Avancé : Module Federation pour micro-frontends
  • Outils : SpeedMeasurePlugin pour profiler builds
Découvrez nos formations Learni sur les outils de build avancés pour maîtriser Webpack en enterprise.