Le truc avec create-vite, c’est que tu l’utilises souvent en mode pilote automatique. Tu veux un projet qui démarre vite, tu tapes la commande, tu codes. Sauf qu’avec create-vite 9, il y a un changement qui ressemble à un détail mais qui peut te coûter cher : la cible navigateurs par défaut bouge. Et quand la target bouge, tu touches à la transpilation, aux features JS autorisées, aux polyfills, et au genre de bugs qui n’apparaissent pas sur ton Mac en Chrome à jour.
Je préfère le dire comme ça : ce n’est pas « une nouvelle version cool ». C’est un changement de contrat. Si tu bootstrap des projets React, ou si tu recrées souvent un repo à partir du template, tu veux cadrer ça explicitement. Sinon tu vas découvrir la régression le jour où un client ouvre l’app dans un navigateur d’entreprise, un webview un peu vieux, ou un environnement SEO/preview pas tout à fait « normal ».
Ce qui change vraiment quand la target par défaut avance
Quand la target par défaut devient plus moderne, ton code final (celui qui part en prod) peut se retrouver avec des syntaxes et des APIs plus récentes. C’est souvent positif pour le poids et la perf, mais ça retire aussi une couche de « compat implicite » que tu avais sans le savoir.
Le piège, c’est que ton cerveau compare deux choses qui ne sont pas comparables. Tu compares « ça marche chez moi » (navigateur récent, dev server, HMR, environnement propre) avec « ça marche partout » (parc réel, extensions, webviews, vieux terminaux, pages embarquées dans des iframes, etc.). Le changement de target ne casse pas forcément tout au démarrage. Il casse parfois un seul écran, un seul parcours, sur un seul device. Le genre de bug que tu ne reproduis pas, puis que tu finis par « fixer » à l’aveugle.
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€ !
Pourquoi React est souvent le premier à prendre
React n’est pas « fragile », mais React a une particularité : c’est un écosystème qui empile vite des transformations. Entre TypeScript, JSX, les plugins, les macros, les optimisations de compilation et les bibliothèques qui shipent du code moderne, tu peux te retrouver avec une app où la compat finale dépend de plusieurs endroits à la fois.
Et les symptômes, eux, ne crient pas forcément « target navigateur ». Tu vois plutôt des erreurs du type « unexpected token », des écrans blancs, des hydrations qui partent en vrille, un embed tiers qui ne se charge plus, ou un script analytics qui plante et coupe la suite. Rien de très glamour. Juste de la prod qui brûle lentement.
Le réflexe qui sauve : rendre la cible explicite (et la versionner)
Le bon move, c’est de ne jamais dépendre d’un défaut pour un sujet aussi structurant que la compat. Tu dois décider une cible et l’écrire noir sur blanc. Ensuite seulement, tu acceptes (ou pas) les compromis poids/perf/compat.
Dans Vite, le point d’ancrage le plus clair, c’est la config. Tu peux fixer la target côté build, et aussi côté transpilation esbuild. L’idée n’est pas de te donner « la bonne target universelle » (elle n’existe pas). L’idée, c’est de figer ton contrat pour que ton projet ne change pas de comportement juste parce que tu as relancé un create-vite ou bumpé un major.
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
// Décide ta cible explicitement, ne la laisse pas au défaut du moment.
// Exemple volontairement générique : adapte à ton parc réel.
build: {
target: 'es2020'
},
esbuild: {
target: 'es2020'
}
})
Si tu utilises une browserslist dans ton repo (souvent pour PostCSS/Autoprefixer, ou pour documenter le parc), garde-la cohérente avec ta target. Pas besoin d’en faire une religion, mais éviter d’avoir « browserslist très large » et « build target très moderne », ça t’épargne des incompréhensions quand quelqu’un lit le projet ou quand un bug remonte.
{
"browserslist": [
">0.5%",
"last 2 versions",
"not dead"
]
}
Attention : Vite ne te « donne » pas des polyfills comme par magie
Une confusion fréquente, c’est de penser « transpilation = compat ». Non. Transpiler te règle la syntaxe. Les APIs manquantes (exemple classique : certaines features Web ou JS selon ton parc) nécessitent des polyfills, et Vite n’a jamais eu vocation à en injecter partout par défaut.
Si ton parc inclut des navigateurs vraiment en retard, ou des webviews exotiques, tu dois assumer une stratégie. Sur certains projets, ça passe par accepter que ces environnements ne sont pas supportés. Sur d’autres, ça passe par une solution du type @vitejs/plugin-legacy et un vrai test de non-régression. Mais ne laisse pas ce sujet dans un angle mort, parce que le jour où ça casse, tu finiras à ajouter un polyfill en urgence sans comprendre pourquoi ça marchait « avant ».
Le test qui compte : valider ton parc réel, pas ton navigateur à toi
Le plan anti-régression, ce n’est pas « ouvrir la home sur Chrome ». Ce qui marche bien, c’est un petit noyau de parcours E2E (Playwright ou autre) qui tourne sur le build de prod, et qui est exécuté dans une CI. Même deux ou trois tests, tant qu’ils couvrent les pages qui embarquent le plus de JS et les intégrations les plus pénibles (auth, paiement, éditeur riche, maps, i18n, etc.).
Et si tu as une vraie contrainte de parc (entreprise, administration, devices terrain), tu dois aussi accepter de tester sur ce parc. Pas forcément en continu, mais au moins à chaque saut majeur d’outillage. Un navigateur « un peu vieux » peut très bien passer toute ta suite unit tests et casser à l’exécution sur un détail de runtime. C’est exactement le genre de surprise qu’une target qui avance peut provoquer.
create-vite 9 côté React : les templates bougent, et ça n’est pas neutre
Le deuxième sujet que j’ai vu passer, c’est la partie templates React. create-vite 9 fait évoluer ces templates, et notamment la variante autour du React Compiler. Si tu pars sur ce template, tu retombes sur un fait très concret : aujourd’hui, ce chemin s’appuie sur Babel. Donc tu récupères une chaîne de build plus lourde que « React + Vite » en mode minimal.
Ce n’est pas un jugement de valeur. React Compiler est une vraie piste d’optimisation, mais si ton équipe s’attend à une stack « full transpile Rust ultra rapide », tu risques d’avoir un petit choc. Dans les retours terrain, c’est un point qui revient : ça fonctionne, mais ça peut être plus lent, et ça remet des dépendances Babel dans un projet que beaucoup pensaient « débarrassé de Babel » depuis des années.
À noter aussi : create-vite 9 corrige des détails de template (dépendances nécessaires) pour éviter des installs incomplètes. Typiquement, si tu utilises le template React Compiler, vérifie que ton lockfile est cohérent, que l’installation est propre, et que la CI reconstruit bien depuis zéro. C’est bête, mais les « ça marche sur ma machine » reviennent vite quand un template a changé récemment.
Plugins, macros, transformations : là où les migrations Vite deviennent piégeuses
Les migrations Vite « simples » le sont tant que tu restes dans un usage standard. Mais dès que tu as des plugins qui transforment du code, des macros (i18n, CSS-in-JS, etc.), ou des outils qui s’accrochent au pipeline de bundling, tu es sur une zone sensible. Et les discussions autour des évolutions de bundling (Rolldown et compagnie) montrent bien le problème : tu peux avoir un plugin qui marche, puis qui casse sur une version, puis qui remarche après patch. Ce n’est pas rare.
Mon approche, c’est d’être un peu parano. Si tu relies un projet existant à un template create-vite plus récent, ou si tu fais un saut de versions Vite en même temps que tu changes des plugins React, tu réduis ton observabilité. Quand ça casse, tu ne sais plus ce qui a causé quoi. Sépare les mouvements quand tu peux, et garde un diff clair.
Mon plan anti-régression « sobre » quand je bootstrap ou migre un React + Vite
Je fige d’abord la cible. Vraiment. Je préfère choisir une target légèrement conservatrice et la faire évoluer consciemment, plutôt que de me retrouver avec une target qui avance au gré des majors. Ensuite, je fais tourner un build prod local, je sers le dist, et je teste dans des environnements moins confortables que mon browser quotidien. Pas pour faire du musée, juste pour attraper les erreurs de runtime évidentes.
Ensuite seulement, je regarde les optimisations. React Compiler, SWC, transformations, tout ça vient après. L’erreur classique, c’est de vouloir optimiser un pipeline alors qu’on n’a même pas fixé le contrat de compat. Résultat, tu gagnes 200 ms au build, et tu perds une demi-journée parce qu’un navigateur secondaire te renvoie un écran blanc.
Et si tu bosses en équipe, fais-toi une règle simple : « la compat navigateur ne doit pas être un implicite ». Un repo qui annonce sa target (dans la config, dans la doc, et dans les tests) est un repo qui survit aux upgrades d’outillage. Les autres finissent avec des patchs d’urgence, des polyfills ajoutés au hasard, et des débats stériles sur qui a cassé quoi.