Aller au contenu principal

L'état de Babel

· 28 min de lecture
Traduction Bêta Non Officielle

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 →

Sujets précédents : Feuille de route de Babel #4130, 6.0 #2168

Ne manquez surtout pas la section Communauté.

Également publié dans le Calendrier de l'avent du Web 2016 de Mariko Kosaka !

Un peu d'histoire

Sebastian a créé "6to5" en septembre 2014. Ce qui est intéressant, c'est qu'il l'a développé pour répondre à sa curiosité sur le fonctionnement des langages de programmation. On pourrait penser que le créateur du projet maîtrisait déjà les compilateurs et JavaScript... mais ce n'était pas le cas ! Découvrez son histoire dans son article : ~2015 in Review.

6to5 faisait exactement cela : transformer simplement du code ES6 en ES5. Quand 6to5 est devenu Babel comme mentionné dans Not Born to Die, il s'est transformé en plateforme : une suite d'outils conçus pour créer la prochaine génération d'outils JavaScript. Il ne se contentait plus de compiler ES6 vers ES5, il permettait aux développeurs de construire des outils par-dessus.

Voici quelques-unes de nos étapes clés :

  • Dans 5.0.0, Babel s'est aligné sur le processus TC39 en introduisant les stages, a ajouté l'option de configuration .babelrc et a créé un système de plugins pour les transformations personnalisées.

  • Dans 6.0.0, Babel est devenu modulaire (une idée assez controversée à l'époque). Ce changement majeur a conduit à une fonctionnalité optionnelle (plus de valeurs par défaut) et au concept de Presets et d'options de plugins.

    • Comme mentionné dans son article, Sebastian a rejoint Facebook en juillet 2015 et a travaillé sur tout le développement de Babel 6 sur son temps de travail.
  • 6.3.13 Sebastian a extrait nos outils de build/publication du monorepo pour créer ce qui est devenu Lerna. (Le plus drôle, c'est que James l'a réécrit 3 fois et j'ai dû tout relire)

    • C'est vers cette période que Sebastian et James se sont épuisés sur Babel, et que quelques contributeurs ont pris le relais.
    • Nous avons eu du mal à trouver une direction et à gérer les bugs/demandes, mais nous avons accompli énormément !
  • 6.13.0 a enfin ajouté les Preset Options.

  • 6.14.0 a introduit un latest-preset qui se maintient à jour avec la spécification JavaScript annuelle.

  • 6.16.0 a permis de remplacer le parseur ou le générateur de code.

  • En août, nous avons lancé Babili, un minifieur basé sur Babel.

  • En septembre, nous avons publié la première version de babel-preset-env (lisez la suite pour les détails).

  • Après un an sur Phabricator, nous sommes revenus à GitHub issues grâce uniquement à @danez et à son travail exceptionnel (et sous-estimé).

Si vous utilisez Babel, signalez-le nous via une PR sur notre page utilisateurs !

Aujourd'hui, babel-core est téléchargé plus de 5 millions de fois par mois et près de 60 millions de fois au total, utilisé par des géants comme Facebook/Netflix/Airbnb et d'autres projets open source comme React/Yarn.

Merci à tous pour votre soutien continu ! Nous voulons rester le socle de la chaîne d'outils JavaScript : compilation, linting, minification, codemods, couverture de code, etc.

État actuel

Si vous souhaitez contribuer, consultez les problèmes liés ci-dessous !

Maintenir les plugins Babel pour chaque proposition TC39 dès le Stage 0

TC39 désigne Ecma International, Comité Technique 39 : l'instance qui façonne JavaScript.

Babel utilise le concept des stages de TC39 pour catégoriser ses plugins expérimentaux. Les utilisateurs doivent pouvoir exploiter les fonctionnalités avant leur implémentation complète dans les navigateurs au stage 4 du processus TC39.

Babel est fondamental dans ce processus grâce à sa place dans l'écosystème : modifier un fichier .babelrc est bien plus simple qu'activer un flag navigateur, et développer un plugin Babel est nettement plus rapide qu'implémenter nativement la fonctionnalité dans un navigateur. C'est l'essence même de Babel.

Mais le processus des propositions implique d'importantes itérations : leur syntaxe peut changer ou elles peuvent être abandonnées. Comme TC39 se réunit tous les 2 mois, les plugins doivent être mis à jour au moins à chaque changement de stage pour garder les utilisateurs synchronisés.

Les retours précoces aux champions des propositions et au comité sont extrêmement précieux, bien qu'il soit recommandé d'utiliser les fonctionnalités des stages 0/1/2 avec prudence. Bien que des entreprises comme Facebook exploitent ces fonctionnalités, elles ont créé des codemods pour faciliter les transitions.


Le temps et les ressources manquent pour maintenir chaque plugin, surtout lors des mises à jour des spécifications.


Nous travaillerons ensuite avec :

Problèmes pertinents :

Consultez thefeedbackloop.xyz pour plus d'informations sur TC39 !

Maintenance des autres plugins écosystémiques : JSX/Flow

Babel est vital pour les écosystèmes React et Flow, et nous collaborons étroitement avec les équipes concernées chez Facebook.

Étiquettes de problèmes pertinentes :

babel-preset-env (« autoprefixer » pour Babel)

La compilation JavaScript est une cible mouvante : les spécifications évoluent annuellement, les navigateurs se mettent constamment à jour, et les utilisateurs abandonnent le support d'anciens navigateurs. À première vue, aucune cible fixe ne semble exister pour la compilation du JavaScript.

La compat-table est constamment mise à jour et utilisée pour ce préréglage.

C'est là qu'intervient babel-preset-env : un préréglage Babel déterminant automatiquement les plugins nécessaires en fonction des environnements ciblés.

Son objectif est double : simplicité d'utilisation et efficacité du code produit. Vous spécifiez vos environnements cibles pour exploiter le code natif, et le préréglage sélectionne les plugins requis.

Exemples de configurations

Ciblage de Chrome 55 + les 2 dernières versions des autres navigateurs via browserslist

JavaScript
{
"presets": [
["env", {
"targets": {
"chrome": 55,
"browsers": ["last 2 versions"]
}
}]
]
}

Cibler la version actuelle de Node.js (utilise process.versions.node)

JavaScript
{
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
]
}

Chrome 55 useBuiltIns + webpack 2

JavaScript
{
"presets": [
["env", {
"targets": {
"chrome": 55
},
"modules": false,
"useBuiltIns": true
}]
]
}

Entrée

JavaScript
import "babel-polyfill";

Sortie (diffère selon l'environnement)

JavaScript
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";

Problèmes pertinents :

Linting via babel-eslint

example of eslint

ESLint ne prend pas en charge les nouvelles fonctionnalités linguistiques avant qu'elles n'atteignent le Stage 4 du processus des propositions. Nous maintenons donc babel-eslint (un parseur ESLint personnalisé) pour continuer à linter du JavaScript avec une syntaxe expérimentale.

Ce projet compte parmi les plus complexes : étant une couche de compatibilité entre Babel et ESLint, il nécessite des mises à jour constantes lorsque l'un des projets évolue, avec un risque élevé de modifications inattendues dues au monkey-patching. Il était regrettable de rencontrer des problèmes comme babel/babel-eslint#243 ou babel/babel-eslint#267.

Pour réduire la charge de maintenance, nous souhaitons améliorer l'interopérabilité de notre scope et traversal avec ESLint. Il pourrait même être intéressant d'écrire des règles ESLint en utilisant les API Babel ou vice versa ?

Problèmes pertinents :

Minification

Babili est notre nouveau minifieur basé sur Babel, permettant de produire du code minifié tout en ciblant les derniers navigateurs.

Entrée

JavaScript
class Mangler {
constructor(program) {
this.program = program;
}
}
new Mangler();

Sortie

JavaScript
// ES2015 code -> Babili -> Minified ES2015 Code
class a{constructor(b){this.program=b}}new a;

Consultez notre billet de blog pour plus d'informations.

Étant récemment publié, nous recherchons de nouveaux contributeurs ! De nombreux petits bugs et améliorations sont disponibles pour ceux cherchant un nouveau projet à soutenir !

Codemods / Refactoring / eslint --fix

Un codemod est une modification de code assistée par outil ; un rechercher-remplacer sophistiqué.

Pour remplacer merge({}) par Object.assign({}) (et peut-être plus tard par l'opérateur rest), une simple expression régulière pourrait suffire. Mais vous ne voudriez pas remplacer d'autres parties du code appelées merge comme les imports/exports, chaînes de caractères, commentaires ou variables locales. Pour agir en sécurité, il faut un outil plus puissant modifiant uniquement le code spécifique visé.

Bien que Babel transforme déjà du code en un autre code, il ne se soucie pas du style du code d'entrée en tant que compilateur. Après avoir utilisé Babel avec ses options par défaut pour un codemod, le git diff devient très désordonné.

Voici Recast : un outil qui préserve la mise en forme du code non modifié tout en reformattant proprement les nouveaux nœuds AST.

recast

Dans la capture d'écran ci-dessus, le panneau supérieur gauche montre le code source, tandis que le panneau inférieur droit montre le code transformé après l'exécution du plugin Babel. Dans ce cas, l'outil préserve autant que possible les espaces blancs du code d'origine.

En passant Recast dans les options, Babel peut alimenter l'avenir des codemods.

.babelrc

JavaScript
{
"parserOpts": {
"parser": "recast"
},
"generatorOpts": {
"generator": "recast"
}
}

Exécuter les transformations Babel pertinentes sur le code source et l'écraser :

Shell
babel src -d src

Cette fonctionnalité vient d'être rendue possible, nous travaillons donc à la rendre plus accessible et à explorer ses applications. Consultez le billet 6.16.0 pour plus de détails !

Autres projets connexes : JSCodeshift, js-codemod, Lebab.

Problèmes pertinents :

Couverture de code / Instrumentation

Nous souhaitons prendre en charge des outils comme nyc et babel-plugin-istanbul.

Écosystème de plugins

Grâce à notre communauté dynamique, de nouveaux plugins sont constamment créés : qu'il s'agisse d'une nouvelle façon d'écrire votre CSS dans JSX ou de réécrire vos tests.

Actuellement, on compte > 1200 plugins Babel sur npm.

Nous avons eu des discussions intéressantes sur la manière de développer et soutenir cet écosystème. Surveiller tous les dépôts serait ingérable.

Des bots automatisés pourraient s'avérer utiles pour : créer des plugins/règles ESLint spécifiques, écrire des codemods pour les changements d'API, et intégrer des plugins à nos tests de validation.

  • Devrions-nous lancer une newsletter pour les nouveaux plugins utiles ?

  • Comment enseigner la création de plugins ?

  • Comment améliorer ASTExplorer ?

Documentation (ce site web !)

Les contributions à la documentation ont clairement manqué cette dernière année.

Mais récemment, des améliorations notables ont été apportées :

Nous avons également intégré de nouveaux collaborateurs :

  • @STRML : A ajouté Discourse à toutes les pages GitHub via #875

  • @xtuc : A ajouté la prise en charge de la lecture du README depuis le dépôt babel pour éviter de synchroniser deux copies de la documentation via #990

  • @fredericmarx : A ajouté un bouton de copie dans le presse-papiers pour les extraits de code via #998

  • @seedofjoy : A ajouté une fonctionnalité de redimensionnement pour le REPL via #1003

Quelques idées

  • Tous les plugins devraient inclure des exemples. Il est également possible d'intégrer RunKit ou le REPL.

  • Mettre à jour la FAQ avec les erreurs courantes

  • Documentation API / améliorer le babel-handbook

Problèmes pertinents :

L'avenir

L'avenir

NOTE : Tout ce qui suit peut être modifié ou abandonné. Certains éléments sont peut-être déjà en cours de développement, d'autres sont des suggestions nécessitant une discussion appropriée ou un porteur de projet.

Modifications de l'API des plugins

Il existe beaucoup de confusion concernant la manière dont les plugins et les presets interagissent en termes d'ordre. Cela entraîne des bogues et des problèmes de configuration qui obligent les utilisateurs à placer les plugins avant ou après d'autres de manière non intuitive.

Il existe une grande confusion concernant l'interaction entre plugins et presets, notamment sur l'ordre d'exécution. Cela génère des bugs et des problèmes de configuration obligeant les utilisateurs à placer les plugins avant/après d'autres de manière non intuitive.

Nous discutons actuellement de changements d'API qui pourraient réduire cette confusion. Cependant, comme il s'agit d'une modification fondamentale du cœur de Babel, trouver la meilleure approche pourrait prendre du temps.

Depuis Babel 6, nous utilisons un versionnage "fixé" via Lerna. Cela nous permet de publier plusieurs packages simultanément sous la même version (si le package change). C'est pratique car vous n'avez pas à définir manuellement une version pour chaque package, mais tout évolue ensemble. Le seul cas où cela pourrait causer une erreur est lorsqu'un package introduit un changement cassant : alors tous les packages passent également en version majeure.

Ce point est davantage expliqué dans les notes de Babel mais nous devons encore déterminer le meilleur plan d'action pour le projet.

Que se passe-t-il lorsqu'une spécification Stage 0 passe en Stage 1 avec un changement cassant pour le parseur ? Devons-nous simplement incrémenter la version majeure, regrouper les modifications ou trouver un mécanisme via plusieurs versions de plugins ?

Discussion sur GitHub

Changer la mentalité autour des presets Stage X

Problèmes pertinents :

Vitesse

La performance est une fonctionnalité ! D'autres aspects peuvent être prioritaires (correctifs, conformité aux spécifications, etc.), mais elle reste cruciale à plusieurs niveaux.

  • Comment réduire la taille/temps d'installation, surtout pour les projets multi-packages ? (amélioré par yarn)

  • Comment accélérer l'analyse syntaxique ?

  • Comment créer des plugins plus rapides (et les mesurer individuellement) ?

  • Comment générer plus rapidement le code transformé ?

  • Comment produire un code exécuté plus vite dans le navigateur (https://fhinkel.github.io/six-speed/) ?

Si vous détectez des problèmes dans le code compilé, signalez-les et demandez de l'aide pour proposer une PR !

Problèmes précédents :

Support possible de TypeScript ?

Babel pourrait-il apprendre la syntaxe TypeScript (comme pour Flow) ? Un plugin pourrait supprimer les types TypeScript pour une meilleure interopérabilité.

Cela impliquerait d'analyser la syntaxe spécifique à TypeScript et de la retirer. Cependant, TypeScript inclut des syntaxes non-typées comme enum, nécessitant des discussions supplémentaires.

Exploiter les informations de type ?

Intégrer un système de types (Flow/TypeScript) pour optimiser. Babel pourrait ainsi savoir via ces outils si un identifiant arr est réellement un Array.

Certains plugins effectuent déjà du type checking : babel-plugin-typecheck et babel-plugin-tcomb

Traiter un graphe de dépendances / Opérer sur plusieurs fichiers ?

Cela permettrait une meilleure intégration avec des outils comme Webpack. Les transformations inter-fichiers ou optimisations globales deviendraient possibles, par exemple pour :

  • Un minifier supprimant des propriétés après vérification de leur usage global

  • Détecter les imports/exports manquants ou invalides

  • Discussion sur GitHub

Erreurs de l'analyseur

Améliorer les messages d'erreur comme dans Compiler Errors for Humans.

Évidemment, nous voulons tous des erreurs utiles !

Nous pouvons améliorer l'inférence/estimation de l'intention des utilisateurs pour prévenir des erreurs trop vagues. Signalez-nous les cas où cela se produit !

Problèmes pertinents :

babel-init

Un moyen simplifié de configurer Babel, similaire à l'approche de create-react-app.

  • Créer un .babelrc de zéro via des questions interactives

Idée envisageable :

  • Interroger sur les environnements cibles (navigateurs, node) et transmettre à babel-preset-env

  • Sonder l'intérêt pour les fonctionnalités expérimentales (ajout de plugins spécifiques)

  • Réactiver le package npm babel : en faire le babel par défaut/opt-in/opinionated de Babel 5. Il pourrait utiliser env par défaut avec les latest 2 browsers (sans configuration).

Problèmes pertinents :

Exécuter tc39/test262

test262 vérifie la conformité au brouillon évolutif du futur standard ECMAScript disponible sur tc39.github.io/ecma262, ainsi qu'aux propositions TC39 de stade 3 ou ultérieur. Maintenu par Tom Care (@tcare) avec d'importantes contributions de la communauté ECMAScript.

L'exécution des tests officiels de spécification sur Babel garantit notre conformité ou identifie les écarts. Nous devrons implémenter un filtrage pour les fonctionnalités non-compilables (proxy, TCO, etc.) et créer un système pour examiner les tests échoués, puis ouvrir des issues et PR correspondantes.

Problèmes pertinents :

Tests de fumée/intégration

Un outil complémentaire à Greenkeeper serait utile, ou exécuter des tests avec la branche master de Babel pour détecter les régressions majeures avant publication (inspiré du projet citgm de Node.js). Idéalement, tester les principaux projets open source utilisant Babel.

motiz88/babel-smoke-tests constitue une excellente base ! Existe-t-il déjà des solutions similaires ?

Analyse de programme

La conférence d'Alan Shreve "Journaux de commit idéalisés : simplification du code via le découpage de programme" a inspiré @kentcdodds pour l'implémenter en JavaScript via slice-js.

L'idée générale est que nous disposons de nombreux outils pour nous aider à écrire du code, mais peu pour nous aider à comprendre/lire le code. On peut considérer le code-slicing comme une forme d'élimination ciblée de code mort.

slice-js

Un slice de programme supprime essentiellement du code source les parties non utilisées pour un cas de test exécuté. Si des instructions conditionnelles ou des boucles ne sont pas exécutées dans votre scénario, elles n'apparaîtront pas dans le slice.

  • Outil de grepping sémantique (conscient de l'AST) ?

À l'instar de graspjs, il serait intéressant de pouvoir effectuer un rechercher-remplacer avec l'AST en entrée. Cela permettrait de créer d'autres outils d'analyse : trouver toutes les IIFE dans notre code, compter les appels d'une méthode, ou même dénombrer les Classes dans notre base de code.

babel --settings

Cette commande afficherait toutes les informations (y compris lors d'erreurs). Elle inclurait également des métriques de performance sur la durée d'exécution de chaque plugin.

Unification des parseurs

Des discussions ont eu lieu autour de l'unification des parseurs/AST, notamment dans TheLarkInn/js-parser-discussions et précédemment avec ESTree.

Malheureusement avec Babel 6, nous avons "forké" et notre AST présente quelques différences par rapport à ESTree. Babel vise à supporter les fonctionnalités de stage x alors que d'autres parseurs peuvent se limiter au stage 4. Nous pouvons avoir des priorités différentes concernant la conformité aux spécifications, les performances, les fonctionnalités expérimentales, les messages d'erreur, l'extensibilité ou les releases. Il reste important d'être ouvert aux breaking changes pouvant améliorer l'interopérabilité et la communauté.

Interopérabilité avec Sweet.js ?

Ancienne issue. Peut-être pouvons-nous simplement améliorer l'interopérabilité ?

Support de Node.js

Devrions-nous abandonner le support selon le cycle de vie des versions Node.js ? Combien de temps devrions-nous généralement attendre pour cela ?

  • Voulons-nous continuer à supporter les utilisateurs n'ayant pas encore mis à jour ?

  • Certaines transformations/PR sont bloquées par ceci, en raison d'outils ayant déjà abandonné les anciennes versions.

  • De nombreux autres outils de build comme ESLint l'ont déjà fait.

  • Allons-nous créer une version majeure uniquement pour cela ou planifier d'autres changements en plus ?

  • Issue de discussion

Transition Babel 5 vers 6 / Chemins de mise à jour

La migration vers Babel 6 a été très difficile pour la communauté. La version initiale était un peu précipitée. Bien que nous ayons publié un billet sur la version 6.0, un guide d'installation peu après, et même un outil (maintenant obsolète) pour faciliter la transition, les changements restaient difficiles à appréhender pour les utilisateurs.

Il reste un nombre important d'utilisateurs sur Babel 5 que nous ne voulons pas abandonner. Comment les aider à migrer ? Quelles mesures prendre pour éviter que cela ne se reproduise avec Babel 7 ? Existe-t-il d'autres projets/communautés que nous devrions contacter et soutenir ?

Problèmes pertinents :

Autres sujets ?

D'autres points non abordés ici ? Contactez-nous sur Twitter @babeljs, via notre Slack (inscription sur https://slack.babeljs.io/), en commentant cet article, ou en ouvrant une issue de discussion dans notre dépôt !

Quels projets ou communautés devrions-nous davantage intégrer ? Comment rendre l'expérience des contributeurs plus accueillante ? Comment améliorer la transparence du processus de développement ?

Communauté

Anciennes issues :

On pourrait penser qu'un projet largement adopté attire naturellement plus de contributeurs. Mais comme pour la plupart des projets open source non soutenus par une entreprise, les problèmes de maintenance et de pérennité persistent : épuisement des mainteneurs, migration vers d'autres projets, contraintes professionnelles/familiales.

Comme James l'explique dans Dear JavaScript, l'équipe actuelle de Babel est très réduite.

Babel n'est ni une entreprise, ni une équipe dédiée chez Facebook, ni un projet open source financé par une société. C'est un effort communautaire actuellement porté par quelques personnes, et nous souhaitons que cela grandisse.

Si vous souhaitez contribuer à un outil que vous utilisez, nous espérons que ce sera celui-ci !

Sur quelles issues contribuer ?

Plusieurs de nos projets ont des étiquettes beginner-friendly et help-wanted. Consultez également discussion.

Équipe

Notre équipe principale :

Et ces 3 derniers mois, de nombreux nouveaux collaborateurs :

Équipe principale de Babili :

Comme mentionné précédemment, nous avons de nombreux collaborateurs sur le site :

Inactifs mais toujours une ressource :

Comment contacter l'équipe ?

GitHub

Pour les rapports de bugs et PR, consultez nos dépôts.

Twitter

Contactez-nous sur Twitter via @babeljs - ou mentionnez-nous individuellement.

Personnellement, j'ai rejoint Twitter pour échanger avec les utilisateurs et leur venir en aide. Publier les nouvelles fonctionnalités et changelogs est très utile pour recueillir vos retours !

Slack

Nous y avons une communauté relativement active !

Vous y trouverez des membres passionnés prêts à aider comme Jordan Harband, @ljharb, Jessica Franco, @Jessidhia, Jimmy Jia, @taion, Denis Pushkarev, @zloirock et bien d'autres !

Pour des questions générales, rejoignez #discussion. Pour contribuer ou suivre les développements, consultez #development.

Nous évitons les discussions privées inutiles : je publie généralement les issues/PR en cours pour examen collectif.

Autres

Comment mieux interagir avec la communauté ? Devrions-nous organiser des meetups, participer à des conférences ou animer des hackathons ?

Comment assurer la pérennité de Babel ? Créer une Open Collective, rejoindre une fondation, ou financer un chef de projet ?

Dites-nous ce que vous en pensez ! Qu'attendez-vous de Babel ?


Vous repérez des coquilles ou problèmes ? Envoyez une PR ou commentez sur babel/babel.github.io#1014

Surtout, nous tenons à vous dire que beaucoup d'entre nous ont commencé avec Babel pour apprendre JavaScript, et non parce qu'ils le maîtrisaient déjà. Personnellement, je ne connaissais rien aux compilateurs et venais juste de découvrir l'ES6 quand j'ai découvert le projet. Je suis arrivé ici par une petite étincelle de curiosité et beaucoup d'encouragements. Je souhaite perpétuer cet esprit et espère que nous réussirons ensemble.

Merci infiniment pour votre lecture !

Henry Zhu (@hzoo) (@left_pad)

Un immense merci à toutes ces personnes pour leurs relectures et contributions : @DrewML, @mrjoelkemp, @kentcdodds, @existentialism, @jdalton, @gaearon, @nolanlawson, @jayphelps, @montogeek, @TheLarkInn, @jasonLaster, @benjamn, @addyosmani, @Daniel15, @loganfsmyth, @gr2m, @mathiasbynens, @chicoxyzzy, @bvaughn, @bcoe.