Aller au contenu principal
Site en cours de refonte — quelques pages peuvent bouger ou évoluer.
26 mars 2026

Webpack veut gérer ton CSS tout seul : prépare-toi avant que ça casse

Webpack veut intégrer le CSS (et les CSS Modules) dans le core via experimental.css. Bonne nouvelle… sauf si ton pipeline CSS actuel repose sur des détails qui vont bouger.

11 min de lecture
40 vues
réactions
Partager :
Webpack veut gérer ton CSS tout seul : prépare-toi avant que ça casse

Si tu as déjà passé une demi-journée à comprendre pourquoi ton CSS est nickel en dev mais pété en prod, tu sais un truc : le CSS dans Webpack, c’est rarement “juste du CSS”. C’est une chaîne de loaders, de plugins, d’options, de conventions d’équipe, et parfois de hacks accumulés. Et justement, la roadmap Webpack 2026 annonce un move intéressant : du CSS (et des CSS Modules) gérés dans le core via une option experimental.css, avec l’idée de réduire la dépendance à des plugins historiques comme mini-css-extract-plugin.

Sur le papier, c’est séduisant : moins de tuyauterie, moins de compat, moins de “ça marche chez toi”. Dans la vraie vie, ça veut dire que ton stack CSS actuel mérite une cartographie avant de toucher au moindre flag. Parce que le CSS, c’est là où les différences d’ordre, de split, de minification et de sourcemaps te plantent le plus discrètement.

Le vrai sujet : ton CSS aujourd’hui dépend d’un écosystème, pas de Webpack

La plupart des projets Webpack “adultes” ont un pipeline CSS implicite. Tu importes un .css ou un .module.css, et tout se passe. Sauf qu’en dessous tu as souvent css-loader (modules, url(), import), postcss-loader (autoprefixer, nesting, custom media), éventuellement sass-loader, et très souvent un plugin d’extraction côté prod pour sortir des fichiers CSS (et pas juste injecter dans le JS).

Ce pipeline fait plus que “compiler du style”. Il impose un ordre (qui gagne entre deux imports), une stratégie de runtime (style tags en dev, fichiers en prod), une manière de faire du code splitting CSS, et un niveau de tolérance aux bizarreries (sourcemaps, chemins d’assets, CSS importés depuis des packages). Du coup, quand Webpack dit “on va le faire nativement”, la question n’est pas “est-ce que ça marche”. La question, c’est “est-ce que ça marche pareil”.

Ce que Webpack 2026 veut internaliser avec experimental.css

D’après la roadmap 2026, Webpack pousse une intégration native du CSS et des CSS Modules dans le core via experimental.css. L’intention est claire : réduire l’empilement de plugins pour un cas d’usage ultra-standard, et tracer un chemin vers la suite (y compris la trajectoire vers Webpack 6).

Si tu as vécu l’évolution des bundlers ces dernières années, tu vois le pattern : les “core features” reprennent des trucs qui vivaient en plugins et deviennent un mode officiel, mieux intégré au graphe de dépendances et à l’optimisation. Le bénéfice attendu, c’est moins de friction, moins de combos impossibles à maintenir, et des comportements plus uniformes entre dev et prod. L’inconvénient, c’est que les détails changent, et ces détails sont exactement ceux qui font qu’un CSS est stable en prod.

MiniCssExtractPlugin & co : optionnels, mais pas forcément remplaçables à 1:1

On va être franc : si tu utilises mini-css-extract-plugin, ce n’est pas par passion. C’est parce que tu veux des fichiers CSS en prod, du caching, et une séparation propre JS/CSS. Si Webpack arrive à proposer une extraction équivalente dans le core, beaucoup de projets vont y gagner en maintenance.

Le piège, c’est de croire que “remplacer un plugin” est une opération mécanique. Certains projets ont des réglages fins sur l’ordre des chunks, sur le nommage, sur les runtimes, sur la manière dont les styles sont chargés au premier paint, ou sur la gestion de styles critiques. Et surtout, beaucoup d’équipes se sont habituées à un comportement précis, parfois même à un bug devenu une “feature” dans leur app. Quand tu changes le moteur, tu peux découvrir des dépendances invisibles. Typiquement : un ordre d’injection différent, une CSS specificity qui n’était “ok” que par hasard, ou un code split qui charge une feuille trop tard.

Les risques de migration qui cassent vraiment : ordre, dev/prod mismatch, sourcemaps, split CSS

Le premier risque, c’est l’ordre. Les CSS Modules te protègent partiellement (classes hashées), mais pas totalement. Tu as toujours des styles globaux, des resets, des librairies, des overrides. Quand l’ordre d’évaluation ou d’assemblage change, tu peux te retrouver avec des régressions très localisées, donc très longues à diagnostiquer. Le genre de bug où une modale est parfaite partout sauf sur iOS, sauf sur une route, sauf après une navigation client.

Le deuxième risque, c’est le mismatch dev vs prod. Beaucoup de stacks Webpack injectent les styles en dev (HMR), puis extraient en prod. On s’habitue à ce que ça “ressemble” au même rendu, mais ce n’est déjà pas strictement identique. Si tu actives une feature expérimentale qui change encore la chaîne, tu peux accentuer l’écart. Et ce sont exactement les incidents les plus pénibles : ceux que tu ne reproduis pas en local “en mode dev”.

Le troisième, ce sont les sourcemaps. En CSS, les sourcemaps peuvent devenir inutilisables très vite dès que tu empiles Sass + PostCSS + minification. Si tu dépends de sourcemaps exploitables pour débugger en prod (ou au moins en preprod), tu veux vérifier très tôt que tu ne perds pas cette capacité.

Le quatrième, c’est le code splitting CSS. Certaines apps ont une stratégie fine : styles communs dans un chunk, styles de pages splités, styles de composants chargés à la demande. Un changement d’algorithme d’extraction peut te créer soit trop de CSS (bundle global énorme), soit trop de micro-fichiers (flash de styles, waterfall réseau, perf qui régresse). Et tu ne le verras pas sur un “hello world”. Tu le verras sur une vraie navigation avec cache froid.

Cartographier ton pipeline CSS avant de toucher à experimental.css

Avant de tester quoi que ce soit, je veux savoir à quoi sert chaque brique. Pas “en théorie”, mais “dans ton repo”. Est-ce que tu utilises vraiment PostCSS, et pour quoi ? Est-ce que tes CSS Modules sont partout, ou tu as aussi un gros legacy global ? Est-ce que tu importes du CSS depuis node_modules ? Est-ce que tu as des assets gérés par url() (fonts, images) qui dépendent de la config Webpack ? Est-ce que Sass est central ou marginal ?

Cette cartographie te sert à une chose : éviter la migration “optimiste”. Le scénario classique, c’est “on active le flag, ça build, on ship”. Et deux jours après, tu découvres que ton import d’une lib CSS casse en production parce qu’un chemin d’asset a changé, ou que ton reset n’est plus en premier, ou que la page de login a perdu ses styles parce qu’elle est dans un chunk différent.

Un protocole de test qui marche : pages de référence + captures, pas du feeling

Tester une migration CSS au doigt mouillé, c’est une mauvaise blague. Tu ne vas pas “voir” toutes les régressions, surtout celles qui se déclenchent sur un breakpoint, un navigateur, une police qui met plus de temps à charger, ou une route chargée en lazy.

Ce qui marche bien, c’est de choisir quelques pages de référence qui représentent ton UI réelle : la page la plus dense, une page qui utilise beaucoup de composants, une page avec tables/formulaires, une page avec modales/toasts, une page qui dépend fortement du responsive. Tu fais tourner deux builds (ton pipeline actuel vs le mode experimental), et tu compares visuellement. Si tu as déjà Playwright ou Cypress, tu peux automatiser des screenshots. Sinon, même une comparaison “semi-manuelle” est déjà mille fois mieux que “j’ai cliqué vite fait”.

Et surtout, tu testes prod-like. Pas seulement webpack-dev-server. Tu fais un build de prod, tu sers les assets comme en prod, tu testes cache froid, cache chaud, navigation initiale, navigation interne. C’est là que le split CSS et l’ordre de chargement te rattrapent.

Stratégie progressive : feature flag build, versions pin, et rollback prévu

Si tu as une app en prod, tu ne “switches” pas un pipeline CSS sur un coup de tête, surtout quand c’est estampillé experimental. Le bon move, c’est un mode parallèle. Tu gardes la config actuelle comme référence, tu ajoutes une variante activable par variable d’environnement, et tu compares. Ça te permet d’itérer sans bloquer l’équipe, et de revenir en arrière en une minute si tu tombes sur un cas tordu.

Je suis aussi assez strict sur le versioning dans ce genre de phase : tu pins les versions de Webpack et des briques autour, tu évites d’upgrader trois trucs en même temps, et tu notes précisément ce que tu as changé. Le CSS est un domaine où les “petits” bumps cassent parfois plus que les gros. Un rollback propre fait partie du plan, pas de la panique.

Exemple concret : activer un mode “test” sans casser la config existante

L’idée ici n’est pas de te donner une config magique (ça dépend trop de ton projet), mais de te montrer le pattern que j’utilise quand je veux tester une feature de bundler sans déranger tout le monde.

// webpack.config.js
const useNativeCss = process.env.WEBPACK_NATIVE_CSS === '1';

module.exports = {
  // ... ton setup habituel
  experimental: {
    // Roadmap 2026 : support CSS/CSS Modules via experimental.css
    css: useNativeCss,
  },
};

Tu gardes ton pipeline actuel en place tant que tu n’as pas prouvé que le mode natif couvre ton besoin. Et tu testes. Beaucoup. Le jour où tu vois “ok, c’est stable”, là tu peux commencer à retirer des morceaux, un par un, en vérifiant à chaque retrait que tu ne perds pas une capability dont tu dépendais sans le savoir.

Les cas où je ne migrerais pas tout de suite (même si ça a l’air tentant)

Si ton CSS repose sur une cuisine PostCSS assez poussée (nesting non standard, transformations custom, design tokens injectés, plugins internes), je temporiserais. Pas parce que Webpack ne saura jamais le gérer, mais parce que ton pipeline actuel est peut-être devenu une pièce structurante du design system. Toucher à ça sans fenêtre de stabilisation, c’est demander une série de “petites” régressions qui vont éroder la confiance dans l’outillage.

Si tu as un historique de bugs liés à l’ordre des styles, ou si tu as beaucoup de global CSS legacy, je temporiserais aussi. Le mode natif peut être meilleur à terme, mais il faut lui laisser le temps de se tasser, et toi tu as besoin d’un rendu stable plus que d’un setup élégant.

Enfin, si ton équipe n’a pas de test visuel (même minimal), je mettrais ce chantier derrière la mise en place d’un garde-fou. Le CSS est visuel. Sans filet, tu vas juste “espérer”. Et en prod, l’espoir n’est pas une stratégie.

Mon avis : la promesse est bonne, mais le CSS te rappellera que “ça build” ne veut rien dire

Je suis plutôt content de voir Webpack essayer de simplifier le CSS. La dette plugin est réelle, et c’est fatiguant de devoir maintenir une stack juste pour faire un truc qui devrait être basique en 2026. Mais je ne confonds pas “moins de plugins” avec “moins de risques”. Le CSS est un domaine où les changements subtils font des dégâts très concrets.

Si tu veux profiter du mouvement sans drama, traite ça comme une migration de comportement, pas comme un refactor de config. Mesure, compare, isole, et garde une marche arrière. Tu auras le meilleur des deux mondes : moins de plomberie à terme, et pas de régressions qui te pourrissent un sprint.

Sources

Cet article vous a plu ?

Commentaires

Laisser un commentaire

Entre 10 et 2000 caractères

Les commentaires sont modérés avant publication.

Aucun commentaire pour le moment.

Soyez le premier à donner votre avis !