Suppression des presets de stage de Babel
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Avec la version 7, nous avons décidé qu'il était préférable de cesser de publier les presets de stage dans Babel (par ex. @babel/preset-stage-0).
Cette décision n'a pas été prise à la légère, et nous souhaitons expliquer le contexte des interactions entre TC39, Babel et la communauté.
Un peu d'histoire
Un preset Babel est une liste partageable de plugins.
Les presets de stage officiels de Babel suivaient le processus de maturation TC39 pour les nouvelles propositions de syntaxe en JavaScript.
Chaque preset (ex. stage-3, stage-2, etc.) incluait tous les plugins pour ce stade spécifique ainsi que ceux des stades supérieurs. Par exemple, stage-2 incluait stage-3, et ainsi de suite.
Cela permettait aux utilisateurs souhaitant employer une syntaxe expérimentale d'ajouter simplement le preset, sans avoir à configurer/installer chaque plugin individuellement.
Nous avons en réalité ajouté les presets de stage peu après la sortie de Babel v6 (c'était auparavant un flag de configuration dans la v5). Voici un exemple plus ancien de Babel v6 :
Il était courant de voir ceci dans une configuration :
{
"presets": ["es2015", "react", "stage-0"]
}
Le code source original de babel-preset-stage-0 :
module.exports = {
presets: [
require("babel-preset-stage-1")
],
plugins: [
require("babel-plugin-transform-do-expressions"),
require("babel-plugin-transform-function-bind")
]
};
Problèmes
Ces presets offraient un moyen pratique d'utiliser ce que nous désirions tous : le futur nouveau et brillant, encore « indéterminé » de JavaScript.
Avec le recul, cela a très bien fonctionné ! (Peut-être trop bien ?)
Trop efficace ?
Des langages comme CoffeeScript et des outils comme Traceur ont contribué à établir l'idée de compilation de JavaScript. Babel a rendu encore plus simple l'utilisation d'une syntaxe nouvelle/future et l'intégration avec les outils existants. Les attentes sont passées du scepticisme et de l'inquiétude à une adoption totale de l'expérimental.
Nous ne serions probablement pas là sans l'adoption massive de compilateurs comme Babel : cela a accéléré l'utilisation (et l'enseignement) d'ES2015 auprès d'un public bien plus large. La croissance de React a encore stimulé cet usage, car sa syntaxe JSX, les propriétés de classe et la décomposition d'objets ont conduit les développeurs à mieux connaître ces propositions syntaxiques.
Babel est devenu une configuration unique pour beaucoup, dont on ne se préoccupait plus jamais. Il est devenu l'infrastructure sous-jacente, masquée par d'autres outils jusqu'à ce qu'une SyntaxError, des problèmes de dépendances ou d'intégration surviennent. Il suffisait d'utiliser stage-0.
C'était formidable à certains égards, car cela signifiait que ces idées étaient testées en conditions réelles, y compris en production. Cependant, cela impliquait aussi que de nombreuses entreprises, outils et personnes rencontreraient des difficultés si une proposition changeait significativement (ou était même abandonnée).
Allers-retours
Ces dernières années, nous avons soulevé de nombreuses discussions sur le sort des presets de stage dans #4914, #4955, #7770. J'avais même écrit dans un ancien billet sur Babel 7.0 que nous ne les supprimerions pas 😅.
Cependant, nous avons constaté que maintenir les presets de stage créerait des problèmes même pour Babel lui-même :
-
Une question fréquente était : "Quels presets sont nécessaires pour utiliser les fonctions async ?". La signification exacte de
stage-0restait obscure pour beaucoup, et peu de personnes consultaient sonpackage.jsonou son code source. -
Supprimer un plugin de proposition en Stage 3 (une fois passée en Stage 4) constitue un changement cassant. Ce problème s'aggrave quand on utilise
@babel/preset-envpour éviter de compiler une proposition déjà supportée nativement.
"Décorateurs ES7"
Une partie du problème réside précisément dans la dénomination, et comme on l'entend souvent, trouver le bon nom est difficile.
ES6 a connu de nombreuses appellations : Harmony, ES Next, ES6, ES2015. Face à de nouvelles idées, il est tentant d'utiliser simplement le dernier numéro disponible pour les désigner.
Il est donc facile de rechercher des tweets/articles/conférences évoquant les "Décorateurs ES7", montrant que cette terminologie s'est imposée.
Your reminder that binding with :: is just an experimental proposal at stage 0 and might never become a part of JS. Don't call it "ES7".
— Dan Abramov (@dan_abramov) October 9, 2016
Ce phénomène est compréhensible, mais sa pérennisation crée des attentes biaisées sur l'évolution du langage. Rien de répréhensible — nous apprenons collectivement et nous rappelons mutuellement le fonctionnement de JavaScript.
Jay Phelps a écrit un excellent article sur ce sujet. Il recommande d'utiliser leur "Stage" actuel : "Décorateurs Stage 2", ou simplement "Proposition de Décorateurs".
Dire "Décorateurs ES7" suppose que cette fonctionnalité fera partie d'ES7. J'évoquais cela dans mon dernier article sur la compilation des node_modules, mais un Stage donné ne garantit rien : une proposition peut stagner, reculer ou être abandonnée.
Nous avons voulu souligner ce fait en modifiant les noms des plugins de proposition, passant de @babel/plugin-transform- à @babel/plugin-proposal-.
BabelScript
Proposer des presets pour des propositions aussi précoces peut laisser croire qu'elles sont garanties d'évoluer ou d'avoir une implémentation stable.
TC39 met en garde contre l'usage des propositions Stage 2 ou inférieures, risquant de créer une pression involontaire pour figer les implémentations par crainte de casser du code existant ou de fragmenter l'écosystème (ex. utiliser # plutôt que @ pour les décorateurs).
On plaisante en disant que les développeurs utilisant Babel écrivent du "BabelScript" plutôt que du JavaScript, sous-entendant qu'une fonctionnalité avec plugin Babel serait déjà "figée" ou officielle (ce qui est faux). Pour certains, voir une nouvelle syntaxe/idée (Stage "-1") déclenche immédiatement la question : "Y a-t-il un plugin Babel pour ça ?".
Définir les attentes
Après que des compilateurs comme Babel ont popularisé l'écriture d'ES2015, il était naturel que les développeurs veuillent expérimenter des "fonctionnalités" plus récentes. Chez Babel, cela passait par le flag stage dans les anciennes versions ou les presets stage-x.
Étant la méthode la plus pratique pour adopter toute nouvelle fonctionnalité, il est rapidement devenu l'option par défaut pour les utilisateurs configurant Babel (même si dans Babel v6, par défaut, il ne faisait plus rien, ce qui a provoqué de nombreuses plaintes).
Il est devenu courant de voir "stage-0" utilisé dans les bibliothèques, les boilerplates, les conférences, les tweets et les diapositives.
"Just say no" to
— Ryan Florence (@ryanflorence) July 31, 2015babel?stage=0in production.
Il y a eu beaucoup de bonnes discussions il y a même des années, mais ce n'était pas facile à gérer : nous ne voulions pas pénaliser les utilisateurs qui comprenaient les compromis en ajoutant des console.warn lors de son utilisation, et ne pas avoir l'option du tout semblait déraisonnable à l'époque.
Opter aveuglément pour le Stage 0 (que ce soit par défaut ou non) ou que les utilisateurs choisissent de le faire semble dangereux, mais ne jamais utiliser aucune proposition est excessivement prudent. Idéalement, chacun devrait être en mesure de prendre une décision éclairée sur les types de fonctionnalités qui lui semblent raisonnables et les utiliser judicieusement, quel que soit leur stade. Mike Pennisi a écrit un excellent article sur ces préoccupations.
Ce n'est pas notre intention de menacer, précipiter ou forcer l'adoption de choses spécifiques dans l'écosystème ou JavaScript, mais de maintenir fidèlement les implémentations et discussions autour des nouvelles idées.
Hésitations
Autres considérations
Nous aurions également pu essayer de :
-
Renommer les presets pour mieux indiquer le niveau de stabilité (ne résout pas le problème de versioning)
-
De meilleures stratégies de versioning : versionner les presets indépendamment et les mettre à jour immédiatement si nécessaire, peut-être utiliser
0.x -
Avertir/Erreur pour les anciennes versions obsolètes des presets
Au final, les utilisateurs devraient quand même vérifier à quel stade se trouvent les propositions pour savoir lesquelles utiliser si nous conservions les Stages.
Pourquoi maintenant ?
Pourquoi ne pas les avoir supprimés plus tôt ? Les Stage presets font partie de Babel depuis des années, et il y avait des inquiétudes quant à l'ajout de plus de "complexité" à l'utilisation de Babel. Beaucoup d'outils, de documentation, d'articles et de connaissances tournaient autour des Stage presets. Auparavant, nous pensions qu'il valait mieux maintenir officiellement les presets puisque quelqu'un d'autre les aurait (et les aura) inévitablement créés.
Nous essayons de déterminer le bon niveau de retour : si seul le comité décide de ce qui entre dans le langage, cela peut conduire à des fonctionnalités bien spécifiées mais inutiles, mais si la communauté s'attend à ce que les propositions expérimentales en cours soient considérées comme stables ou utilisables en production sans conséquence, alors nous aurons d'autres problèmes. Nous voulons tous avancer et procéder avec intention : sans précipitation, mais sans être trop prudents. Babel est l'endroit idéal pour cette expérimentation, mais il est nécessaire de connaître les limites.
La suppression des presets serait considérée comme une "fonctionnalité" car cela signifie que quelqu'un devrait prendre une décision explicite d'utiliser chaque proposition, ce qui est raisonnable pour toute proposition étant donné qu'elles ont toutes des niveaux variables d'instabilité, d'utilité et de complexité.
Nous nous attendons pleinement à une certaine contre-réaction initiale, mais nous pensons finalement que la suppression des Stage presets est une meilleure décision pour nous tous à long terme. Cependant, supprimer les options par défaut précédentes ou les Stage presets ne signifie pas que nous ne nous soucions pas de la facilité d'utilisation, des nouveaux utilisateurs ou de la documentation. Nous travaillons avec ce que nous pouvons pour maintenir le projet stable, fournir des outils pour améliorer les choses et documenter ce que nous savons.
Migration
Pour une migration plus automatique, nous avons mis à jour babel-upgrade pour le faire à votre place (vous pouvez exécuter
npx babel-upgrade).
En résumé : nous supprimons les préconfigurations Stage. D'une certaine manière, les utilisateurs devront désormais opter activement et connaître les propositions utilisées, plutôt que de supposer ce qu'ils devraient utiliser, surtout compte tenu de la nature instable de certaines de ces propositions. Si vous utilisez une autre préconfiguration ou une chaîne d'outils (par ex. create-react-app), il est possible que ce changement ne vous affecte pas directement.
Nous avons déprécié les préconfigurations Stage à partir de la version 7.0.0-beta.52. Si vous ne souhaitez pas modifier votre configuration maintenant, nous vous suggérons de figer les versions à beta.54 jusqu'à ce que vous puissiez effectuer la mise à niveau. Après la beta.54, nous générerons une erreur avec un message expliquant comment migrer. Vérifiez également que toutes vos versions sont identiques durant la phase de préversion.
Comme alternative, vous êtes libre de créer votre propre préconfiguration contenant les mêmes greffons et de les mettre à jour comme bon vous semble. À l'avenir, nous pourrions travailler sur un babel-init qui vous aiderait à configurer les greffons interactivement, ou mettre à jour babel-upgrade lui-même pour lister et ajouter les greffons Stage actuels. Peut-être que Babel devrait rester un outil de bas niveau et s'appuyer sur d'autres outils de plus haut niveau ou frameworks comme create-react-app pour gérer ces choix à la place des utilisateurs.
Prévenir le verrouillage des propositions
James DiGioia a récemment écrit un billet sur les changements concernant l'utilisation de l'opérateur pipeline (|>).
Le point principal du billet est que la proposition elle-même est en évolution et offre plusieurs options à explorer. Comme nous souhaitons implémenter les trois possibilités actuelles sous forme de greffons Babel, à la fois pour recueillir des retours sur la spécification et des retours utilisateurs, nous estimons que la façon d'utiliser le greffon devrait également changer. C'est une approche relativement nouvelle pour TC39 et Babel !
Précédemment, nous ajoutions simplement le greffon de proposition à la configuration, et c'était tout. Désormais, nous supprimons le comportement par défaut et demandons aux utilisateurs d'opter pour un indicateur qui précise quelle proposition est choisie, tout en clarifiant qu'il n'existe pas d'option fixe (ni même privilégiée) pour le moment.
{
"plugins": [
- "@babel/plugin-proposal-pipeline-operator"
+ ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }]
]
}
C'est une pratique que nous souhaitons continuer à appliquer à l'avenir, comme un indicateur supplémentaire que ces propositions sont ouvertes aux changements et aux retours de notre part à tous. La suppression des préconfigurations Stage facilite encore cela car auparavant nous devions transmettre ces options même si vous n'utilisiez pas la syntaxe.
Fardeau de maintenance de l'écosystème
Le « budget syntaxique » d'un langage ne s'applique pas seulement à la complexité du langage lui-même, mais peut s'étendre aux outils. Chaque nouvelle syntaxe ajoutée impose un nouveau fardeau aux mainteneurs d'autres projets JavaScript.
Une fois qu'une nouvelle syntaxe est proposée, de nombreux éléments doivent être mis à jour : les analyseurs (babylon), la coloration syntaxique (language-babel), les linteurs (babel-eslint), les frameworks de test (jest/ava), les formateurs (prettier), la couverture de code (istanbul), les minificateurs (babel-minify), et plus encore.
De nombreux problèmes ont été soulevés sur des projets comme acorn, eslint, jshint, typescript, et d'autres, pour qu'ils prennent en charge les propositions Stage 0 simplement parce qu'elles étaient dans Babel. Peu de projets adhéreraient à une politique exigeant de supporter toute proposition, car cela serait extrêmement contraignant à maintenir. À bien des égards, c'est étonnant que nous tentions même de le gérer dans Babel lui-même, compte tenu des mises à jour constantes et de l'instabilité.
Qui effectue ce travail, et est-ce notre responsabilité de veiller à ce que tout fonctionne ? Chacun de ces projets (principalement maintenus par des volontaires) manque d'aide dans presque tous les aspects, et pourtant nous recevons continuellement des plaintes à ce sujet de toutes parts. Comment devons-nous, en tant que communauté, assumer la responsabilité de gérer notre infrastructure (ce qui n'est pas sans rappeler l'open source dans son ensemble) ?
Babel a assumé la charge inhabituelle de supporter ces fonctionnalités expérimentales ; parallèlement, il est raisonnable que d'autres projets adoptent une politique plus conservatrice. Si vous souhaitez voir de nouvelles fonctionnalités du langage supportées à travers l'écosystème, contribuez à TC39 et à ce projet pour faire passer ces propositions au Stage 4.
L'avenir
L'objectif de ce projet est de faire partie du processus TC39 : servir de ressource pour implémenter des propositions récentes (Stage 0-2) et recueillir les retours des utilisateurs, tout en supportant les anciennes versions de JavaScript. Nous espérons que cet article éclaire davantage comment nous essayons, au mieux de nos capacités, de mieux aligner ce projet dans l'écosystème JavaScript. Nous publierons bientôt une RC pour la v7 !
Si vous appréciez cet article et le travail que nous accomplissons sur Babel, vous pouvez me soutenir sur Patreon, demander à votre entreprise de nous sponsoriser sur Open Collective, ou mieux encore, impliquer votre entreprise dans Babel dans le cadre de votre travail. Nous apprécierions cette propriété collective.
Un grand merci à tous les relecteurs ! N'hésitez pas à donner votre avis sur Twitter.