Tu fais une upgrade « tranquille » vers Vite 8 et @vitejs/plugin-react v6. Et là, ton vieux réflexe react({ babel: { plugins: [...] } }) ne sert plus à rien. Pire, ça a l’air de marcher… jusqu’au moment où une macro, un plugin Babel historique ou React Compiler ne se déclenche jamais.
Ce n’est pas toi. C’est un vrai changement d’architecture côté plugin React : Babel n’est plus dans la boucle. Du coup, si ton repo s’était construit autour de « j’injecte un plugin Babel dans Vite », tu dois changer d’endroit où tu branches tes transformations. Et si tu veux activer React Compiler 1.0, il y a un ordre à respecter, sinon tu pars pour deux heures de debug à base de « pourquoi rien ne se passe ».
@vitejs/plugin-react v6 : ce qui change vraiment (oxc à la place de Babel)
Le point clé, c’est celui-là : @vitejs/plugin-react v6 ne repose plus sur Babel pour transformer ton code. Il s’appuie sur oxc pour la partie transformation (JS/TS/JSX/TSX) et garde ses responsabilités « Vite/React » (Fast Refresh, etc.).
Conséquence immédiate : toutes les recettes du type « je passe un plugin Babel via react({ babel: ... }) » deviennent soit ignorées, soit sans effet, soit carrément cassantes selon ce que tu faisais. Et comme ce genre de config était souvent “le” point d’entrée pour du codegen, des macros, des transforms de styled-components, des decorators, ou React Compiler, tu te retrouves avec un build qui compile mais un comportement applicatif qui change.
Sponsorisé par Le Scribouillard
Besoin de contenu optimisé SEO ?
Utilisez la meilleure plateforme française de création de contenu assistée par IA ! Et générez des articles pour moins de 1€ !
Les symptômes qui te mettent sur la piste (config ignorée, erreurs bizarres)
Le symptôme le plus fréquent, c’est le faux positif. Le dev server démarre, aucune erreur flagrante, mais un truc n’est plus transformé. Tu le vois au runtime : une macro qui ne s’exécute plus, une lib qui attendait une transformation Babel et se retrouve avec du code « brut », ou un plugin qui était censé réécrire des imports et ne le fait plus.
Autre signal : tu peux passer des options Babel dans la config et ça ne change strictement rien. Tu as l’impression que Vite « n’écoute pas ». En réalité il écoute, mais il n’y a plus le moteur Babel derrière, donc il n’y a plus personne pour exécuter tes plugins.
Et si tu essayes d’activer React Compiler en suivant un ancien tuto, tu peux tomber sur des erreurs difficiles à relier à la cause : warnings qui parlent de transformations JSX, comportements de memoization qui ne changent pas, ou simplement… aucune différence, parce que le plugin n’a jamais tourné.
React Compiler 1.0 avec Vite 8 : l’installer “au bon endroit” (et dans le bon ordre)
React Compiler, aujourd’hui, se branche via un plugin Babel. Donc si le plugin React n’embarque plus Babel, tu dois rajouter un passage Babel toi-même dans la pipeline Vite.
L’approche la plus propre (et la plus proche des retours terrain récents), c’est d’utiliser @rolldown/plugin-babel comme plugin Vite. L’idée : tu exécutes Babel (avec React Compiler) sur tes fichiers React, puis tu laisses @vitejs/plugin-react faire son boulot derrière pour l’intégration React/Vite.
Le détail qui fait gagner du temps : l’ordre des plugins. Si tu lances Babel après le plugin React, tu te tires une balle dans le pied, parce que tu arrives trop tard dans la chaîne de transformations. Dans les faits, tu veux que la passe Babel s’exécute très tôt.
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'
export default defineConfig({
plugins: [
// 1) On remet une passe Babel explicite pour React Compiler
babel({
// Important : cible bien les fichiers concernés
extensions: ['.js', '.jsx', '.ts', '.tsx'],
babelHelpers: 'bundled',
plugins: [
// React Compiler 1.0
['babel-plugin-react-compiler', {}],
],
}),
// 2) Puis le plugin React (Fast Refresh, intégration Vite)
react(),
],
})Oui, c’est contre-intuitif si tu as vécu des années avec « le plugin React gère Babel ». Mais avec v6, ton mental model doit changer : Vite fait tourner une chaîne de plugins. Si tu as besoin de Babel, tu le mets dans la chaîne. Point.
Un conseil très pragmatique : ne commence pas par empiler 4 plugins Babel. Branche React Compiler, vérifie que tu observes un changement réel, puis seulement après tu réintroduis tes autres transforms. Sinon tu vas débugger un plat de spaghetti.
« Ok, mais moi j’avais Babel pour autre chose » : macros, styled-components, emotion
Le cas classique, c’est le repo qui avait “juste” un plugin Babel pour un confort de dev, et qui l’a oublié dans un coin. Avec le switch oxc, ça devient visible. Si tu utilises des choses comme des macros, ou des transformations qui attendent Babel (typiquement certaines optimisations ou réécritures autour de CSS-in-JS), tu dois assumer que ce n’est plus “gratuit”.
Dans ce contexte, remettre Babel via un plugin dédié est souvent le choix le plus simple, parce que tu récupères ton écosystème de transforms sans réécrire ton code. Par contre, ce choix a un coût : tu remets une étape de compilation sur une partie du code. En dev, ça peut passer crème. Sur un très gros monorepo, ça peut se sentir. Le bon arbitrage, c’est d’être strict sur le périmètre : uniquement ce qui en a besoin, pas tout le projet “par habitude”.
Et garde en tête que « ça compilait avant » n’est pas un argument technique : si ton plugin Babel existait, c’est qu’il faisait quelque chose. Le jour où il ne tourne plus, tu le découvres à l’endroit le plus pénible possible, au runtime ou en CI.
Decorators, TypeScript, monorepo : les coins où ça se complique vite
Les decorators, c’est typiquement le genre de feature qui révèle instantanément « qui transforme quoi ». Si tu avais un setup Babel qui gérait des decorators (legacy ou la version plus récente), la migration vers oxc côté plugin React ne va pas magiquement continuer de les supporter comme avant. Là, tu as deux stratégies : soit tu réalignes ton projet sur ce que TypeScript peut produire et ce que ton bundler accepte, soit tu assumes une passe Babel ciblée sur les fichiers qui utilisent cette syntaxe.
TypeScript, lui, est rarement le problème en tant que tel. Le piège, c’est plutôt le mix TS + plugins Babel qui faisaient du “post-traitement” après le TS. Si tu as un monorepo, c’est encore plus sensible parce que tu peux te retrouver à transformer du code provenant de workspaces voisins, avec des patterns d’include/exclude qui ne matchent plus. Et quand ça ne matche pas, ça ne crashe pas forcément : tu obtiens juste un sous-ensemble du code transformé, donc un comportement incohérent selon le package.
Mon retour terrain : dans un monorepo, il vaut mieux être explicite sur ce que tu passes dans Babel. Si tu “attrapes tout”, tu vas ralentir pour rien. Si tu n’attrapes pas assez, tu auras des bugs fantômes selon le chemin d’import.
Stratégie de rollback (quand tu dépends encore trop de Babel)
Il y a des repos où la migration “full oxc + un peu de Babel à côté” est réaliste. Et il y a des repos où c’est un mensonge : tu as 10 plugins Babel, des conventions internes basées dessus, ou un historique de transforms maison. Dans ce cas, la meilleure stratégie n’est pas de forcer la migration en une soirée.
Ce que je considère comme un rollback acceptable, c’est de rester temporairement sur une version de plugin React qui colle à ton pipeline, le temps de découpler proprement tes besoins Babel. Le but n’est pas de rester bloqué six mois, c’est d’éviter la migration « héroïque » qui flingue la vélocité et te laisse avec une config instable que personne n’ose toucher.
Le point important : si tu rollback, fais-le consciemment, documente-le dans le repo, et ouvre un ticket pour sortir Babel au bon endroit. Sinon, tu vas juste repousser la douleur… avec un futur upgrade encore plus violent.
Mon avis : ce changement est sain, mais il te force à être honnête sur ta toolchain
Le move vers oxc côté @vitejs/plugin-react, je le trouve plutôt logique. Moins de Babel “par défaut”, c’est souvent plus rapide, plus simple, et ça pousse l’écosystème à arrêter de brancher Babel pour tout et n’importe quoi.
Mais ça expose aussi une vérité : beaucoup de projets React ont une dette de compilation. Des plugins ajoutés au fil des années, plus personne ne sait exactement pourquoi, et qui deviennent des mines quand tu changes un maillon. La bonne réponse, ce n’est pas de râler contre Vite. C’est de remettre de la clarté : qui transforme quoi, où, et pour quelle raison.
Si tu veux activer React Compiler 1.0 aujourd’hui, la voie “propre” avec Vite 8, c’est d’assumer une passe Babel dédiée. Ensuite, tu regardes froidement ce que tu peux jeter, ce que tu peux remplacer, et ce que tu gardes parce que ça te fait vraiment gagner du temps.