Aller au contenu principal

Mise à niveau vers Babel 7 (API)

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 →

Dirigez les utilisateurs vers ce document lors de la mise à niveau vers Babel 7.

Consultez également le guide de migration v7 pour d'autres changements au niveau utilisateur.

Tous les paquets Babel

Prise en charge de NodeJS

high

La prise en charge de Node.js 0.10 et 0.12 a été abandonnée car ces deux versions ne sont plus maintenues.

Modifications des exports

medium

L'utilisation du plugin add-module-exports a été abandonnée pour les paquets Babel.
Il était nécessaire auparavant pour éviter un changement cassant dans nos exportations.
Si vous importez un paquet Babel dans une bibliothèque, vous devrez peut-être utiliser .default avec require plutôt qu'import.

@babel/core

ast est désormais désactivé par défaut pour des raisons de performance (la plupart des outils ne l'utilisent pas) babel/babel#7436.

La classe Pipeline, exposée publiquement mais non documentée, a été supprimée. Utilisez directement les méthodes de transformation exposées par @babel/core babel/babel#5376.

Les méthodes utilitaires babel.util.* ont été supprimées, et util.EXTENSIONS a été déplacé vers babel.DEFAULT_EXTENSIONS babel/babel#5487.

Les appels à babel.transform ou à toute autre fonction de transformation peuvent retourner null si le fichier correspond à un motif ignore ou ne correspond pas à un motif only babel/babel#5487.

L'option opts.basename exposée sur state.file.opts a été supprimée. Si vous en avez besoin, reconstruisez-la à partir de opts.filename babel/babel#5467.

resolveModuleSource a été supprimé. Nous recommandons d'utiliser l'option 'resolvePath' de babel-plugin-module-resolver@3 babel/babel#6343

babel.analyse a été supprimé car ce n'était qu'un alias de babel.transform.

path.mark() a été supprimé car nous ne l'utilisions pas et il peut être implémenté dans votre propre plugin.

babel.metadata a été supprimé car les métadonnées du plugin généré sont toujours incluses dans le résultat.

path.hub.file.addImport a été supprimé. Utilisez plutôt le module @babel/helper-module-imports.

+  import { addDefault } from "@babel/helper-module-imports";
function importModule(pkgStore, name, path) {
- return path.hub.file.addImport(resolvePath(pkgStore, name, path), 'default', name);
+ return addDefault(path, resolvePath(pkgStore, name, path), { nameHint: name });
}

Modifications de configuration

Nous avons apporté des changements majeurs au fonctionnement de la recherche de configuration :

Par défaut, lors de la recherche de fichiers .babelrc pour un fichier donné, s'arrêter au package.json.

Pour tout fichier donné, Babel v6 remontait la hiérarchie des répertoires jusqu'à trouver un fichier de configuration.
Votre projet pourrait casser s'il utilisait un fichier de configuration hors du package (comme dans le répertoire personnel).

Ajoute la prise en charge d'un fichier babel.config.js similaire à Webpack

Pour éviter de casser le fonctionnement des monorepos (dont Babel lui-même), nous introduisons un nouveau fichier de configuration qui supprime la nature hiérarchique des configurations.

Une option root est incluse, qui par défaut correspond au répertoire de travail courant pour localiser le fichier. Elle n'est pas chargée relativement, ce qui garantit une gestion correcte des liens symboliques, alors qu'auparavant vous deviez peut-être coder en dur les chemins dans webpack.

Consultez la documentation de babel.config.js pour plus d'informations : configuration à l'échelle du projet

Ce fichier combiné avec la nouvelle propriété overrides et env permet d'avoir un seul fichier de configuration fonctionnel pour tous les fichiers d'un projet, plutôt que d'utiliser plusieurs fichiers de configuration par dossier.

Nous excluons également node_modules par défaut et ne recherchons que dans la racine, sauf si vous optez pour la configuration d'un tableau via l'option .babelrcRoots, par exemple "babelrcRoots": [".", "node_modules/pkgA"]

Vérification de la version de Babel #7450

Les plugins peuvent vérifier qu'ils sont chargés avec une version spécifique de Babel. L'API exposera une méthode assertVersion, à laquelle vous pouvez passer une version semver.

L'utilitaire declare est utilisé pour maintenir la compatibilité descendante avec la v6.

JavaScript
import { declare } from "@babel/helper-plugin-utils";

export default declare(api => {
api.assertVersion(7);
// ...
});

Plugins et presets Babel

Il prend actuellement comme premier paramètre l'objet babel, puis les options du plugin/preset, et enfin le dirname

JavaScript
module.exports = function(api, options, dirname) {};

babel-parser (anciennement Babylon)

Suppression de l'option plugin * #301 low

Cette fonctionnalité avait été ajoutée initialement dans la v6.14.1 (17 novembre 2016), il est donc peu probable qu'elle soit encore utilisée.

Cette option fourre-tout a été supprimée ; vous devez désormais spécifier explicitement les plugins à activer.

Nous pensions que ce serait pratique pour les outils afin d'éviter des mises à jour constantes de configuration, mais cela empêchait aussi d'introduire facilement des changements cassants.

Avant :

JavaScript
babelParser.parse(code, {
plugins: ["*"],
});

Vous pouvez retrouver l'ancien comportement avec :

JavaScript
babelParser.parse(code, {
plugins: [
"asyncGenerators",
"classProperties",
"decorators",
"doExpressions",
"dynamicImport",
"exportExtensions",
"flow",
"functionBind",
"functionSent",
"jsx",
"objectRestSpread",
],
});

Voir les options de plugins de Babylon.

Le plugin decorators renommé en decorators-legacy medium

Ce changement d'alignement correspond à l'option legacy de @babel/plugin-proposal-decorators. Un nouveau plugin decorators a été implémenté pour la proposition de décorateurs révisée.

Les deux versions des propositions ayant des syntaxes différentes, il est fortement recommandé d'utiliser decorators-legacy jusqu'à l'implémentation complète de la nouvelle sémantique dans Babel.

Suppression du plugin classConstructorCall #291 low

@babel/traverse

Suppression de la prise en charge des liaisons flow babel/babel#6528

Cette modification s'explique par le fait que declare var foo ne crée pas une liaison locale mais représente une liaison globale.

getFunctionParent ne retournera plus Program, utilisez plutôt getProgramParent #5923. low

Il était incohérent qu'une fonction nommée getFunctionParent retourne aussi Program, c'est pourquoi ce comportement a été supprimé.

Pour obtenir le comportement équivalent, vous devrez apporter une modification telle que

- path.scope.getFunctionParent()
+ path.scope.getFunctionParent() || path.scope.getProgramParent()

Les API de remplacement/suppression de chemin renvoient désormais un tableau de nouveaux chemins low

Par exemple, utiliser Path#insertBefore ou Path#replaceWith renverra désormais toujours un tableau des chemins nouvellement insérés/remplacés.

JavaScript
const node = t.nullLiteral();
const [replaced] = path.replaceWith(node);
replace.node === node; // => true

Cela est particulièrement utile lors de l'insertion de plusieurs nœuds dans une portée supérieure, car vous pouvez immédiatement appeler les API Path sur le nouveau Path du nœud.

JavaScript
const parent = path.findParent(() => /* some selection criteria */);
const helperPaths = path.unshiftContainer("body", helpers);
// helperPaths can now be referenced, manipulated, etc.

Changements de l'AST

Ajout du nœud InterpreterDirective #7928

Babylon analysait déjà les "shebangs" (#!env node) mais les plaçait dans un commentaire du nœud Program. Nous créons désormais un nœud dédié pour cela.

Ajout d'un nouveau champ interpreter au nœud Program.

JavaScript
extend interface Program {
interpreter: InterpreterDirective;
}

Ajout du nœud InterpreterDirective

JavaScript
interface InterpreterDirective <: Node {
type: "InterpreterDirective";
value: string;
}

Renommage des constructeurs de nœuds JSX* et TS* (package @babel/types)

La casse a été modifiée : jsx et ts sont désormais en minuscules.

- t.jSXIdentifier()
+ t.jsxIdentifier()

En général, nous avons différencié les types de nœuds avec TypeAnnotation pour Flow et TSTypeAnnotation pour TypeScript, de sorte que pour les nœuds de type partagés, TypeScript utilise un préfixe TS.

Suppression du champ .expression de ArrowFunctionExpression

Le champ expression a été supprimé pour éliminer deux sources de vérité distinctes et éviter que les plugins aient à les synchroniser manuellement. Vous pouvez désormais simplement vérifier si le corps de la fonction est un BlockStatement ou non :

  return {
visitor: {
ArrowFunctionExpression({ node }) {
- if (node.expression) {
+ if (node.body.type !== "BlockStatement") {
// () => foo;
}
}
}
};

Jetons supprimés

Dans les versions précédentes, les tokens étaient toujours attachés à l'AST au niveau supérieur. Dans la dernière version de @babel/parser, nous avons supprimé ce comportement et l'avons désactivé par défaut pour améliorer les performances de l'analyseur. Toutes les utilisations dans Babel lui-même ont été supprimées et @babel/generator n'utilise plus les jetons pour le pretty printing.

Si votre plugin Babel utilise actuellement des tokens, évaluez si cela est encore nécessaire et essayez de supprimer leur utilisation si possible. Si votre plugin dépend réellement de la récupération des jetons, vous pouvez le réactiver, mais ne considérez cette option qu'en dernier recours car cela affectera les performances des utilisateurs.

Pour l'activer, vous devez définir l'option tokens de babylon sur true. Vous pouvez le faire directement depuis votre plugin.

JavaScript
export default function() {
return {
manipulateOptions(opts, parserOpts) {
parserOpts.tokens = true;
},
...
};
}

Renommés

Les nœuds suivants ont été renommés :

Name 6.xName 7.xExamplePR
ExistentialTypeParamExistsTypeAnnotationtype A = B<*>;#322
NumericLiteralTypeAnnotationNumberLiteralTypeAnnotationtype T = 0;#332

En plus des nœuds AST, toutes les fonctions correspondantes dans @babel/types ont également été renommées.

 import * as t from "@babel/types";

return {
- ExistentialTypeParam(path) {
- const parent = path.findParent((path) => path.isExistentialTypeParam());
- t.isExistentialTypeParam(parent);
+ ExistsTypeAnnotation(path) {
+ const parent = path.findParent((path) => path.isExistsTypeAnnotation());
+ t.isExistsTypeAnnotation(parent);

- return t.existentialTypeParam();
+ return t.existsTypeAnnotation();
},
- NumericLiteralTypeAnnotation(path) {
- const parent = path.findParent((path) => path.isNumericLiteralTypeAnnotation());
- t.isNumericLiteralTypeAnnotation(parent);
+ NumberLiteralTypeAnnotation(path) {
+ const parent = path.findParent((path) => path.isNumberLiteralTypeAnnotation());
+ t.isNumberLiteralTypeAnnotation(parent);

- return t.numericLiteralTypeAnnotation();
+ return t.numberLiteralTypeAnnotation();
}
};

Remplacés

Pour les nœuds AST suivants, la valeur du champ variance est passée d'une simple chaîne à un nœud AST dédié appelé Variance. #333

Ce champ n'est disponible que lorsque le plugin flow est activé dans babylon.

  • ObjectProperty

  • ObjectMethod

  • AssignmentProperty

  • ClassMethod

  • ClassProperty

  • Property

Le type du nouveau nœud Variance ressemble à ceci :

JavaScript
type VarianceNode = {
type: "Variance",
kind: "plus" | "minus",
};
 return {
Property({ node }) {
- if (node.variance === "plus") {
+ if (node.variance.kind === "plus") {
...
- } else if (node.variance === "minus") {
+ } else if (node.variance.kind === "minus") {
...
}
}
};

Modifications d'emplacement

Les informations de localisation de ObjectTypeIndexer ont été modifiées pour exclure les points-virgules. Cette modification aligne le comportement sur le flow-parser pour une cohérence des données de localisation. #228

Exemple :

JavaScript
var a: { [a: number]: string };
 {
"type": "ObjectTypeIndexer",
"start": 9,
- "end": 29,
+ "end": 28,
"loc": {
"start": {
"line": 1,
"column": 9,
},
"end": {
"line": 1,
- "column": 29
+ "column": 28
}
}
}

Suppressions

ForAwaitStatement

Le nœud AST ForAwaitStatement a été supprimé et remplacé par le champ await dans le nœud ForOfStatement #349

 interface ForOfStatement <: ForInStatement {
type: "ForOfStatement";
+ await: boolean;
}
 return {
- ForAwaitStatement(path) {
- ...
+ ForOfStatement(path) {
+ if (path.node.await) {
+ ...
+ }
}
};

RestProperty et SpreadProperty

Les deux nœuds AST RestProperty et SpreadProperty ont été supprimés au profit de la réutilisation des nœuds RestElement et SpreadElement #384

 return {
SpreadElement(path) {
- ...
- },
- SpreadProperty(path) {
- ...
+ if (path.parentPath.isObjectExpression()) {
+ ...
+ } else if (path.parentPath.isArrayExpression()) {
+ ...
+ }
},
RestElement(path) {
- ...
- },
- RestProperty(path) {
- ...
+ if (path.parentPath.isObjectPattern()) {
+ ...
+ } else if (path.parentPath.isArrayPattern()) {
+ ...
+ }
}
};

Consultez notre PR de mise à jour pour Babel et la spécification AST de Babylon pour plus d'informations.