Oxlint v1.72 et Oxfmt v0.57 livrent le cycle crates v0.138, unifient l'AstBuilder et retirent le repli Prettier pour CSS/GraphQL

Oxlint v1.72 et Oxfmt v0.57 livrent le cycle crates v0.138, unifient l'AstBuilder et retirent le repli Prettier pour CSS/GraphQL

lschvn

Oxlint apps_v1.72.0 et oxfmt apps_v0.57.0 sont sortis ensemble dans la soirée du 29 juin 2026, sur la base de crates_v0.138.0. Cette version est le cycle v0.138 que les notes de version v1.71 prédisaient explicitement : « la dernière version apps avant la version crates v0.138 qui arrivera lundi 2026-06-29 ». Le cycle achève la migration AstBuilder qui courait sur les versions v0.135 à v0.137, retire le repli Prettier pour CSS / LESS / SCSS et GraphQL dans oxfmt, et livre la plus grande entrée de perf unique de l'étirement v0.137 → v0.138 : la mémoïsation value_type qui transforme une chaîne d'addition arithmétique de 20 000 termes de 6,1 secondes à 4,7 millisecondes.

Cet article couvre la version apps Oxlint v1.72.0, la version apps Oxfmt v0.57.0, et la version crates_v0.138.0 ensemble parce que les trois sont conçues pour sortir comme un tout. Oxlint et oxfmt récupèrent la dernière ligne crates au moment de la version, et les changements cassants de ce cycle sont concentrés dans la couche crates.

Unification AstBuilder : la migration v0.135 → v0.138 aboutit

La plus grande histoire du cycle v0.138 est l'unification des anciennes et nouvelles API AstBuilder dans le crate oxc_ast. La migration court depuis au moins v0.135 début juin et constitue le plus grand changement d'API interne qu'Oxc ait fait depuis la réécriture du minifier.

Le pattern est de cinq PR dans cette version qui déplacent la surface API vers un builder unique. #23876 (overlookmotel) restreint le module oxc_ast::builder à exporter uniquement le type AstBuilder et la sentinelle NONE. #23834 (overlookmotel) fait passer oxc_ecmascript à la nouvelle AstBuilder. #23831 (overlookmotel) fait passer le transformer à la nouvelle AstBuilder. #23875 (overlookmotel) supprime la duplication interne en unifiant les builders. #23877 (overlookmotel) marque les méthodes AstBuilder héritées comme #[deprecated]. Le cycle ajoute aussi un flag de feature Cargo disable_old_builder pour oxc_ast (#23886, #23888) afin que les crates en aval puissent activer le flag et voir ce qui casse avant que les méthodes héritées ne soient supprimées.

Le côté allocateur reçoit son propre lot de changements. #23675 (overlookmotel) renomme le trait AllocatorAccessor en GetAllocator. #23676 (overlookmotel) fait passer GetAllocator::allocator à &self au lieu de self. #23781 (overlookmotel) fait prendre &GetAllocator aux méthodes Str et Ident. Ensemble, les trois changements achèvent la migration vers une API d'allocateur par emprunt : les appelants n'ont plus besoin de cloner ou de posséder un allocateur pour construire des chaînes et des identifiants.

Pour les utilisateurs d'oxlint et oxfmt, rien de tout cela n'est visible. Pour les crates en aval qui construisent des couches AST personnalisées sur Oxc, c'est le plus grand changement cassant en trois cycles. Les notes de version signalent la fenêtre de migration : les méthodes héritées portent des annotations #[deprecated] maintenant, compileront avec des avertissements, et seront supprimées dans un cycle futur. L'équipe signalait cela depuis deux cycles, les notes de version v0.137 avertissant déjà du changement cassant dans oxc_ast.

L'entrée de perf phare : la mémoïsation value_type transforme O(n²) en O(n)

La plus grande entrée de perf visible par l'utilisateur en v0.138 est la PR #23929 (Dunqing) : perf(minifier): memoize value_type to remove its O(n^2) re-walk on long binary chains. Le peephole post-order du minifier évalue Expression::value_type à chaque nœud, et sur une longue chaîne binaire associative à gauche l'évaluation parcourt à nouveau tout le sous-arbre gauche (to_primitivevalue_typeto_primitive → …). Pour N nœuds le coût total était O(N²), et le cas dominant est celui des chaînes d'addition arithmétique non repliables : un a + a + … + a de 20 000 termes prenait 6 118 ms à minifier tandis que les phases de parsing et de sémantique étaient linéaires.

Le correctif mémoïse value_type par adresse de nœud sur MinifierState, avec un point de coupure unique à la méthode récursive Expression::value_type. Chaque nœud est calculé une seule fois, donc le coût total devient O(N) amorti. Le cache est exposé comme hooks opt-in sur GlobalContext (cached_value_type / cache_value_type), et seul le TraverseCtx<MinifierState> du minifier fournit un vrai cache. Tout autre appelant (WithoutGlobalReferenceInformation, la passe d'évaluation de constantes, l'analyse d'effets de bord, le harnais unitaire value_type) conserve le comportement non mis en cache exact précédent. Le cache est vidé au point unique de mutation (record_mutation, touché par chaque replace_* / drop_*) et à chaque reset par passe.

Les chiffres, directement tirés de la description de la PR :

entréeavantaprèseffet
a + a + … × 4 000234 ms0,9 mspassage à l'échelle 4,07x → 2,09x (O(n²) → O(n))
a + a + … × 8 000953 ms1,9 mslinéaire à partir d'ici
a + a + … × 20 0006 118 ms4,7 ms≈1300x plus rapide
antd.js (code réel)78,1 ms65,4 ms≈16% plus rapide sur entrée réelle

Le point clé est que les chaînes d'addition arithmétique sur la sortie minifiée (celles qu'on trouve dans le code numérique généré et dans les gros polyfills) chutent de trois ordres de grandeur. Les bundles réels chutent de 16% au premier passage, les gains se composant sur des entrées plus grandes.

Le cycle comporte cinq autres entrées de perf qui méritent d'être signalées. semantic: Flatten hoisting_variables to avoid per-scope map allocation (Lawrence Lin) supprime l'allocation de map par scope qui se déclenchait à chaque mise à jour de variable hissée. isolated-declarations: Pool scope maps to avoid per-scope alloc/rehash (Boshen) mutualise les scope maps utilisés par oxc_isolated_declarations pour que l'alloc/rehash par fonction disparaisse. minifier: Bail member-expr folding before the side-effect walk (Lawrence Lin) plie les cas simples des chaînes a.b.c.d avant la marche des effets de bord. parser: Avoid span lookup for arrow expression body (camc314) supprime une recherche de hashmap par expression fléchée. Côté formateur, formatter_core: Add printable-ASCII fast path to TextWidth (Lawrence Lin) offre au calcul de largeur de ligne du formateur un fast path quand le texte est de l'ASCII imprimable pur, ce qui couvre la grande majorité de la sortie formatée.

Il y a aussi un cluster de trois PR qui déplacent l'allocation de nœuds AST hors de Box::new_in vers une allocation d'arène directe : parser: Allocate AST nodes in arena directly (overlookmotel), minifier: Allocate AST nodes in arena directly (overlookmotel), et isolated_declarations: Allocate AST nodes in arena directly (overlookmotel). Ensemble, ils remplacent l'indirection Box::new_in par une écriture directe en bump allocator, supprimant une allocation heap par nœud AST dans le parseur, le minifier, et le pipeline isolated-declarations.

Oxfmt v0.57 retire le repli Prettier pour CSS / LESS / SCSS / GraphQL

Le plus grand changement structurel d'oxfmt est le retrait du repli Prettier pour les grammaires CSS et GraphQL. Avant v0.57, oxfmt pouvait formater les fichiers CSS / LESS / SCSS et GraphQL, mais le faisait en déléguant à un Prettier groupé pour ces grammaires. v0.57 retire le repli et formate les deux grammaires nativement en Rust.

Le côté CSS arrive sous le nom d'oxc_formatter_css (leaysgur) et est connecté via l'entrée BREAKING Format parser:css,less,scss files + css-in-js by oxc_formatter_css (leaysgur). Le crate est une implémentation de formateur autonome qui prend les parseurs CSS / LESS / SCSS existants, parcourt l'AST, et émet une sortie compatible Prettier. Les notes de version mentionnent explicitement le css-in-js comme pris en charge : les template literals de style styled-components et Emotion, qu'oxfmt détecte déjà et route vers le parseur CSS, sont maintenant formatés par oxc_formatter_css plutôt que par le shim Prettier.

Le côté GraphQL arrive sous le nom d'oxc_formatter_graphql (leaysgur) et est connecté via l'entrée BREAKING Support draft syntax with removing prettier fallback (leaysgur). La partie « draft syntax » est la partie vraiment nouvelle : l'implémentation GraphQL précédente d'oxfmt gérait la spec stable 2021 ; la nouvelle gère la syntaxe draft GraphQL October 2021 et la syntaxe working-draft utilisée par Apollo Federation et Yoga. C'est une vraie fonctionnalité, pas juste un renommage : le repli Prettier ne pouvait pas non plus gérer la draft syntax, donc la mise à niveau comble aussi un vrai écart format-on-save pour les utilisateurs sur la stack Apollo.

Deux PR de parité avec Prettier rapprochent la sortie des nouveaux formateurs de celle de Prettier : formatter_css: Improve major prettier diffs (leaysgur) et formatter_graphql: Improve major prettier diffs (leaysgur). Les notes de version signalent que des diffs réels sur les bases de code existantes sont encore attendus (le pattern typique « premier passage change quelques lignes, passages suivants idempotents »), mais l'écart est bien plus petit qu'il ne l'était en v0.56.

La version ajoute aussi formatter_css: Handle frontmatter language (leaysgur), qui route le frontmatter Markdown dans les fichiers CSS (par exemple le bloc --- en haut du bloc <style> d'un SFC Vue quand il a des métadonnées frontmatter) vers le parseur frontmatter plutôt que de le traiter comme du CSS, et le fast path ASCII imprimable dans TextWidth mentionné plus haut.

La vue d'ensemble est qu'oxfmt n'est plus un « formateur JS / TS avec un sidecar Prettier pour tout le reste ». Après v0.57 les chemins JS / TS / JSON / JSONC restent sur le formateur interne (ce qui est le cas depuis v0.54), et CSS / LESS / SCSS / css-in-js et GraphQL les rejoignent. Les grammaires restantes que Prettier gère (Markdown, YAML, HTML) ne sont pas dans le périmètre d'oxfmt ; oxfmt les laisse explicitement à Prettier et aux parseurs Rust de Prettier 3.9 qui sont arrivés le 27 juin.

Le cycle touche aussi la commande de migration : fix(oxfmt): update --migrate prettier (leaysgur) remet au propre la commande de migration de configuration Prettier → oxfmt pour gérer les nouveaux formateurs CSS / GraphQL internes. La commande reste le chemin recommandé pour amener une configuration Prettier existante dans un projet oxfmt ; la mise à jour v0.57 ajoute les nouvelles grammaires à la table de conversion.

Oxlint v1.72 fonctionnalités et la décharge de perf

La version apps Oxlint v1.72.0 livre trois fonctionnalités, dix-huit corrections de bugs, et vingt-trois entrées de performance sur la base de crates_v0.138.0. La fonctionnalité phare est linter/react: Implement suggestion for no-unknown-property (Mikhail Baev), qui ajoute un Quick Fix à la règle React no-unknown-property. Avant v1.72 la règle signalait le problème sans action de code ; les éditeurs signalaient la propriété comme inconnue mais le développeur devait la renommer manuellement. Après v1.72 l'éditeur peut proposer un renommage sur place vers la propriété connue la plus proche.

La deuxième fonctionnalité est ast: Unify old and new AstBuilders (overlookmotel), la même unification qui motorise la version crates_v0.138.0. Côté apps, le chemin d'import bascule vers l'AstBuilder unifié, sur quoi le travail de règles de ce cycle se construit.

La troisième fonctionnalité est linter: Add schema for eslint/no-restricted-import (Sysix). Le schéma permet aux utilisateurs d'exprimer les tableaux paths et patterns de no-restricted-import via le schéma de configuration plutôt qu'en JSON brut, ce qui comble un écart de longue date dans le chemin de migration de configuration ESLint → oxlint.

Les dix-huit corrections de bugs vont des faux positifs de cas limite aux correctifs anti-panique. La plus marquante est linter/prefer-called-exactly-once-with: Avoid out-of-bounds slice panic at end of file (Jerry Zhao), qui a fermé une vraie panique qui pouvait crasher le linter sur les fichiers de test où l'assertion était la dernière expression. Autres correctifs notables : linter/unicorn/custom-error-definition: Handle non-ascii class names (camc314), linter/eslint/no-negated-condition: Add autofix for negated conditions (Yagiz Nizipli), linter/eslint/prefer-destructuring: Skip AssignmentExpression autofixes (camc314), et linter/eslint/no-restricted-globals: Handle shadowed locals (camc314).

Les vingt-trois entrées de performance continuent l'histoire du bucketed-dispatch v1.71. Les entrées phares : linter/jsx-a11y: Skip lowercasing non-aria attribute names (Lawrence Lin), qui supprime une allocation to_ascii_lowercase par attribut JSX ; linter/typescript/no-unsafe-declaration-merging: Use keyed binding lookup (Marius Schulz), qui remplace une recherche linéaire par la même table keyed-binding que le bucketed dispatch v1.71 a introduite ; linter/eslint/no-unused-vars: Precompute exported bindings (camc314) ; linter/unicorn/prefer-number-properties: Speed up global checks (camc314) ; linter/eslint/no-script-url: Match javascript: prefix without allocating (Lawrence Lin) ; et linter: Skip traversal without this expressions (camc314), qui court-circuite une classe de règles quand il n'y a aucune this-expression dans le fichier. Combinées avec la base bucketed-dispatch v1.71, les entrées de perf v1.72 amènent oxlint au point où le temps mural de la plupart des règles est dominé par le parcours d'arbre, pas par le churn d'allocation interne aux règles.

Les corrections de bugs du linter incluent aussi linter/jsx-a11y/role-supports-aria-props: Ignore nullish prop values (Mikhail Baev) et linter/eslint/no-warning-comments: Avoid dropping generated regex patterns (camc314), qui ferment toutes deux des écarts de faux positifs sur du JSX réel. Le côté LSP reçoit lsp: Normalize user config path to watch pattern (Sysix), qui corrige un bug de résolution de chemin LSP de longue date sur Windows.

La fonctionnalité Vue typeof define keys

La PR #23605 par Alexander Lichter ajoute transformer_plugins: Support typeof define keys. La PR ajoute le support des clés typeof à l'intérieur du pattern de macro define sur lequel le plugin compiler-macros de Vue s'aligne. Les macros Vue defineProps, defineEmits, defineModel, defineSlots, et autres acceptent une forme runtime (defineProps<typeof import('./foo').bar>()), et l'implémentation transformer_plugins précédente ne reconnaissait pas cette forme. Après v0.138, le crate transformer_plugins reconnaît les clés typeof comme sous-pattern du corps de macro, donc le code TypeScript résultant conserve ses imports de types à travers l'expansion de macro.

Le pattern est partagé par les macros de l'écosystème Vue qui reposent sur defineProps. defineI18nLocale et defineI18nRoute de vue-i18n, les macros d'auto-import de Nuxt (defineNuxtConfig, defineNuxtPlugin), et les patterns de macro des setup stores de pinia acceptent tous une référence typeof import(...) dans le corps de macro. Avant cette PR, le transformer soit échouait à matcher la macro (le chemin de repli générait la macro comme un appel no-op), soit, pire, traitait le token typeof comme une valeur et cassait le tracking d'imports de types.

La PR est aussi le premier changement côté Oxc du cycle v0.138 avec un contributeur de l'écosystème Vue dessus. Alexander Lichter est le mainteneur de vue-router et un contributeur fréquent de la conversation sur les compiler macros Vue ; le support typeof débloque un problème de longue date dans l'écosystème vue-i18n et constitue le signal le plus clair de ce cycle que la surface transformer_plugins se rapproche d'être utilisable sur des bases de code Vue réelles sans un passage vue-tsc en amont.

À surveiller

Trois signaux pour les deux à trois prochaines semaines. Premièrement, surveillez la ligne de patch v0.138.1 et tout signalement de problème de rétro-compatibilité sur la migration AstBuilder : les méthodes héritées sont marquées #[deprecated] dans ce cycle, mais les crates en aval qui construisent des AST personnalisés sur Oxc vont maintenant avoir des avertissements et des cassures au cycle suivant. Le cluster de PR autour de #23877 est l'endroit à surveiller ; si un crate en aval (rolldown, biome, le port Rolldown de Vite, parcel) ouvre un ticket sur la nouvelle forme d'AstBuilder, attendez-vous à un cycle v0.139 avec un guide de migration explicite. Deuxièmement, surveillez l'arrivée d'Oxfmt v0.58 avec une entrée de parité de compat graphql-ou-css. Les PR de parité avec Prettier (#23327, #23419) ont substantiellement réduit l'écart, mais les notes de version signalent que des diffs réels sont encore attendus ; une entrée v0.58 qui ramènerait le nombre de diffs à zéro sur une base de code CSS / GraphQL représentative confirmerait que les nouveaux formateurs sont prêts pour la migration en production. Troisièmement, surveillez l'arrivée de la mémoïsation value_type dans oxc_isolated_declarations ou oxc_transformer. La conception de la PR #23929 est explicite : le cache est opt-in via des hooks sur GlobalContext, et seul le minifier fournit un vrai cache dans ce cycle. Le prochain cycle est l'endroit naturel pour que le transformer et isolated-declarations opt-in ; si c'est le cas, les pipelines de strip-de-types obtiendront le même gain de perf sur les chaînes arithmétiques que le minifier vient d'obtenir.

La leçon plus large est celle que l'article Prettier 3.9 a faite il y a deux jours : la toolchain JavaScript est en train d'être reconstruite sur la stack Rust Oxc, une grammaire à la fois, et le cycle v0.138 ferme deux grammaires supplémentaires (CSS / LESS / SCSS et GraphQL côté oxfmt) et achève une migration d'API interne (AstBuilder + GetAllocator côté crates). Le même pattern apparaît dans la migration SDK de Cline, dans l'unification Vite+ de Vite (la bannière sur le site Oxc), et dans l'intégration Bun + Anthropic. La forme de 2026 à travers l'écosystème Oxc est une séquence de grandes réécritures d'architecture livrées par étapes, chaque cycle marquant un composant supplémentaire comme « terminé » et libérant le cycle suivant pour se concentrer sur les écarts restants.

Questions fréquentes

Cline 4.0.1 annule la migration SDK après les régressions de 4.0.0 ; 4.0.2 ramène le code SDK avec des correctifs pour l'effort de raisonnement et ClinePass

Cline a publié v4.0.1 le 28 juin 2026 et v4.0.2 le 29 juin 2026 (github.com/cline/cline), un cycle de récupération en deux étapes pour la migration SDK de v4.0.0 livrée le 26 juin. v4.0.1 livre l'extension VS Code 3.89.x d'avant le SDK sous un numéro de version 4.0.1, construite à partir d'une branche dédiée `legacy-extension` via un nouveau workflow `ext-vscode-publish-legacy.yml`, pour résoudre les régressions signalées dans 4.0.0 (aperçus de diff cassés dans l'éditeur, erreurs run_commands pendant les éditions de fichiers, flux d'édition de fichiers cassé avec GLM 5.2 et MiniMax M3 via Ollama). v4.0.2 restaure le chemin de code basé sur le SDK par-dessus la même branche legacy, en ajoutant le support de l'effort de raisonnement (incluant `xhigh`) pour les modèles thinking de DeepSeek (#11938), une couche de contrôle d'effort de raisonnement centralisée pour ClinePass (#11954), des identifiants Z.ai canoniques (#11951), un correctif de remplacement des variables d'environnement dans la webview (#11955), un polissage des métadonnées ClinePass et Z.ai (#11958), et un correctif de paramètre par défaut pour focus chain (#11960). La CLI v3.0.32 sort le même jour avec les améliorations de compaction de contexte du SDK v0.0.54 et le polissage de l'onboarding ClinePass. La séquence montre un projet qui récupère une migration majeure en 72 heures en faisant avancer la branche legacy plutôt qu'en annulant le travail SDK.

Articles connexes

Plus de couverture avec des sujets et tags en commun.

Vite 8.1.0 stable : Bundled Dev Mode (15x au démarrage sur 10k composants React), imports WASM ESM et Chunk Import Map, server.fs.deny étendu avec .npmrc et clés privées
tooling

Vite 8.1.0 stable : Bundled Dev Mode (15x au démarrage sur 10k composants React), imports WASM ESM et Chunk Import Map, server.fs.deny étendu avec .npmrc et clés privées

Vite 8.1.0 stable, publié le 2026-06-23 par la Vite Team (announcing-vite8-1), fait passer Bundled Dev Mode d'un flag expérimental à un point d'entrée documenté --experimental-bundle (15x plus rapide au cold start sur une app React à 10 000 composants, 10x sur les full reloads, et Linear rapporte 3x plus rapide au rendering de cold start, ~40% sur les full reloads), stabilise les imports .wasm directs via WASM ESM Integration et le build.chunkImportMap de la 8.1-beta du 2026-06-15, rapproche Lightning CSS du statut de défaut en ajoutant external-CSS-in-CSS et les dépendances fichiers des plugins, bumpe Rolldown à 1.1.2 (1.1.3 suit le même jour), épingle rolldown avec un tilde range pour que les patchs remontent sans PR Vite, étend server.fs.deny avec .npmrc, .yarnrc.yml et *.{key,p12,pfx,cer,der}, et émet un warning runtime quand envFile: false est utilisé.
Oxlint v1.71 et Oxfmt v0.56 livrent les gains des crates v0.137, ajoutent 18 nouvelles règles de linter et domptent la traversée du cycle de vie React avec un refactor en itérateur streamed
tooling

Oxlint v1.71 et Oxfmt v0.56 livrent les gains des crates v0.137, ajoutent 18 nouvelles règles de linter et domptent la traversée du cycle de vie React avec un refactor en itérateur streamed

Oxlint apps_v1.71.0 et oxfmt apps_v0.56.0, tous deux publiés le 2026-06-22, bouclent le cycle des crates v0.137 côté apps. Oxlint v1.71 reprend la nouvelle passe de minifier `treeshake pure typed arrays` (#23469), le correctif `prefer-query-selector` à sélecteur composé, 28 corrections de bugs de lint (en grande partie le travail de réécriture de fixer de Yunfei He), 13 entrées de performance ancrées sur un refactor de dispatch de règles en buckets (#23450, #23452, #23482-#23486, #23489, #23492), et le démarrage de Tokio uniquement pour le LSP dans oxlint (#23447). Oxfmt v0.56.0 livre 9 corrections de bugs (normalisation CRLF pour le texte supprimé par `// @ts-ignore` dans #23701 et #23702, le correctif de panique de chaîne de membres #23698, la préservation du `export default` avec cast de type #23697) et 3 entrées de performance de formatter qui suppriment les copies d'arena sur le texte bigint, littéral numérique et littéral de chaîne. v1.71 est la première release d'apps depuis v1.70.0 le 2026-06-15, et la dernière avant la release de crates v0.138 qui arrivera le lundi 2026-06-29.
SWC v1.15.43 intègre le React Compiler comme transformée de première classe, corrige un bug silencieux du minifier sur les littéraux de gabarit, et aligne `unsafe_math` avec Terser
tooling

SWC v1.15.43 intègre le React Compiler comme transformée de première classe, corrige un bug silencieux du minifier sur les littéraux de gabarit, et aligne `unsafe_math` avec Terser

SWC v1.15.43, publié le 2026-06-22 avec swc_core v71.0.3, livre le React Compiler Rust comme transformée SWC configurable via .swcrc jsc.transform.reactCompiler (PR #11917, 54 fichiers, 12 986 ajouts) ; corrige un bug silencieux du minifier de littéraux de gabarit où `compress` supprimait le texte après la dernière interpolation du gabarit de gauche lors de la concaténation de deux littéraux de gabarit (#11939) ; conditionne Number(x) -> +x à la fois à `unsafe: true` ET `unsafe_math: true` pour suivre terser v4.3.11+ (#11944, #11949) ; corrige la portée des brand checks ES2022 pour les propriétés privées (#11953) ; et embarque sept corrections internes du React Compiler (#11940, #11943, #11946, #11950, #11951, #11952, #11957) ainsi qu'un correctif du parser pour autoriser les builds sans feature par défaut (#11956) et une entrée de doc sur la portée de sécurité des entrées non fiables (#11937).

Commentaires

Connexion Connectez-vous pour participer à la conversation.

Pas encore de commentaires. Soyez le premier à partager vos pensées.