Mise à niveau vers Babel 7
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 →
Consultez ce document pour la migration vers Babel 7. Voir ici pour les changements d'API/d'intégration.
Comme chaque changement cassant n'affecte pas tous les projets, nous avons classé les sections par probabilité d'impact sur les tests lors de la mise à niveau.
Tout Babel
La prise en charge de Node.js 0.10, 0.12, 4 et 5 a été abandonnée #5025, #5041, #7755, #5186
Nous vous recommandons vivement d'utiliser une version plus récente de Node.js (LTS v8) car les versions antérieures ne sont plus maintenues. Consultez nodejs/LTS pour plus d'informations.
Cela signifie simplement que Babel lui-même ne fonctionnera pas sur les anciennes versions de Node. Il peut toujours produire du code qui s'exécute sur d'anciennes versions de Node.
Changements de recherche de configuration
Pour plus d'informations, lisez notre comparaison 6.x vs 7.x.
Babel rencontrait précédemment des problèmes avec node_modules, les liens symboliques et les monorepos. Nous avons apporté des modifications : Babel s'arrêtera à la limite du package.json au lieu de remonter la chaîne. Pour les monorepos, nous avons ajouté un fichier babel.config.js centralisant la configuration (ou une config par package). La version 7.1 introduit l'option rootMode pour des recherches supplémentaires si nécessaire.
Dépréciation des préréglages annuels
Le préréglage "env" existe depuis plus d'un an et remplace complètement certains préréglages précédemment recommandés.
-
babel-preset-es2015 -
babel-preset-es2016 -
babel-preset-es2017 -
babel-preset-latest -
Une combinaison des éléments ci-dessus ^
Ces préréglages doivent être remplacés par "env".
Dépréciation des préréglages stage
Nous supprimons les préréglages stage au profit d'une utilisation explicite des propositions. Consultez le README stage-0 pour les étapes de migration.
Pour automatiser cette opération, exécutez npx babel-upgrade (PR ajouté ici).
Suppression des polyfills de propositions dans @babel/polyfill
Suivant la même logique, nous avons retiré les polyfills de propositions de @babel/polyfill.
Actuellement, @babel/polyfill est principalement un alias de core-js v2. Source
Auparavant, il s'agissait simplement de 2 imports :
import "core-js/shim"; // included < Stage 4 proposals
import "regenerator-runtime/runtime";
Si vous souhaitez utiliser des propositions, vous devrez les importer indépendamment. Importez-les directement depuis le package core-js ou un autre package npm.
Par exemple :
// for core-js v2:
import "core-js/fn/array/flat-map";
// for core-js v3:
import "core-js/features/array/flat-map";
Voici la liste des polyfills de propositions Stage < 3 dans core-js v2 :
Details
// core-js v2
// Stage 3
import "core-js/fn/string/trim-left";
import "core-js/fn/string/trim-right";
import "core-js/fn/string/match-all";
import "core-js/fn/array/flat-map";
import "core-js/fn/array/flatten"; // RENAMED
import "core-js/fn/global";
// Stage 1
import "core-js/fn/symbol/observable";
import "core-js/fn/promise/try";
import "core-js/fn/observable";
// Stage 1 Math Extensions
import "core-js/fn/math/clamp";
import "core-js/fn/math/deg-per-rad";
import "core-js/fn/math/degrees";
import "core-js/fn/math/fscale";
import "core-js/fn/math/iaddh";
import "core-js/fn/math/isubh";
import "core-js/fn/math/imulh";
import "core-js/fn/math/rad-per-deg";
import "core-js/fn/math/radians";
import "core-js/fn/math/scale";
import "core-js/fn/math/umulh";
import "core-js/fn/math/signbit";
// Stage 1 "of and from on collection constructors"
import "core-js/fn/map/of";
import "core-js/fn/set/of";
import "core-js/fn/weak-map/of";
import "core-js/fn/weak-set/of";
import "core-js/fn/map/from";
import "core-js/fn/set/from";
import "core-js/fn/weak-map/from";
import "core-js/fn/weak-set/from";
// Stage 0
import "core-js/fn/string/at";
// Nonstandard
import "core-js/fn/object/define-getter";
import "core-js/fn/object/define-setter";
import "core-js/fn/object/lookup-getter";
import "core-js/fn/object/lookup-setter";
// import "core-js/fn/map/to-json"; // Not available standalone
// import "core-js/fn/set/to-json"; // Not available standalone
import "core-js/fn/system/global";
import "core-js/fn/error/is-error";
import "core-js/fn/asap";
// Decorator metadata? Not sure of stage/proposal
import "core-js/fn/reflect/define-metadata";
import "core-js/fn/reflect/delete-metadata";
import "core-js/fn/reflect/get-metadata";
import "core-js/fn/reflect/get-metadata-keys";
import "core-js/fn/reflect/get-own-metadata";
import "core-js/fn/reflect/get-own-metadata-keys";
import "core-js/fn/reflect/has-metadata";
import "core-js/fn/reflect/has-own-metadata";
import "core-js/fn/reflect/metadata";
Gestion des versions/dépendances
La plupart des plugins/packages de premier niveau ont désormais une peerDependency sur @babel/core.
Renommages des packages
babylondevient@babel/parser
Vous pouvez toujours utiliser la version raccourcie des noms de packages (supprimer preset- ou plugin-) dans la configuration, mais par souci de clarté je préfère utiliser le nom complet (peut-être devrions-nous simplement abandonner cette pratique, car elle n'économise pas tant de frappe).
{
- "presets": ["@babel/preset-react"],
+ "presets": ["@babel/react"], // this is equivalent
- "plugins": ["@babel/transform-runtime"],
+ "plugins": ["@babel/plugin-transform-runtime"], // same
}
Packages scopés
Le changement majeur est le passage définitif à des packages scopés (les noms de dossiers dans le monorepo restent inchangés mais le nom dans le package.json est modifié).
Cela élimine les conflits de noms accidentels ou intentionnels, sépare clairement des plugins communautaires et simplifie la convention de nommage.
Vos dépendances doivent être modifiées ainsi :
babel-cli → @babel/cli. Globalement, nous avons remplacé babel- par @babel/.
Usage dans la configuration
Vous pouvez toujours utiliser la notation raccourcie pour les presets ou plugins. Cependant, à cause du passage aux packages scopés, vous devez spécifier @babel/ comme vous le feriez pour un preset personnalisé.
module.exports = {
presets: ["@babel/env"], // "@babel/preset-env"
plugins: ["@babel/transform-arrow-functions"], // same as "@babel/plugin-transform-arrow-functions"
};
Passage à -proposal- pour les propositions TC39
Tout plugin n'appartenant pas à une release annuelle (ES2015, ES2016, etc.) doit être renommé avec -proposal. Cela indique clairement qu'une proposition n'est pas officiellement dans JavaScript.
Exemples :
-
@babel/plugin-transform-function-binddevient@babel/plugin-proposal-function-bind(Stage 0) -
@babel/plugin-transform-class-propertiesdevient@babel/plugin-proposal-class-properties(Stage 3)
Cela implique qu'une proposition passant au Stage 4 nécessitera un renommage du package.
Suppression de l'année dans les noms de packages
Certains plugins contenaient -es3- ou -es2015- dans leur nom, ce qui était superflu.
@babel/plugin-transform-es2015-classes est devenu @babel/plugin-transform-classes.
"use strict" et this dans CommonJS
Dans Babel 6, les transformations ES6 modifiaient systématiquement tous les fichiers traités, sans vérifier la présence effective d'imports/exports ES6. Cela remplaçait les références à this au niveau fichier par undefined et ajoutait "use strict" en tête de tous les modules CommonJS traités par Babel.
// input.js
this;
// output.js v6
"use strict"; // assumed strict modules
undefined; // changed this to undefined
// output.js v7
this;
Cette fonctionnalité a été restreinte dans Babel 7 : pour la transformation transform-es2015-modules-commonjs, le fichier n'est modifié que s'il contient des imports ou exports ES6. (Note de l'éditeur : Cela pourrait changer à nouveau si nous intégrons https://github.com/babel/babel/issues/6242, nous devrons donc revoir cela avant publication).
// input2.js
import "a";
// output.js v6 and v7
"use strict";
require("a");
Si vous comptiez sur Babel pour injecter automatiquement "use strict" dans tous vos modules CommonJS, vous devrez explicitement utiliser le plugin transform-strict-mode dans votre configuration Babel.
Séparation des presets React et Flow
babel-preset-react incluait toujours le plugin flow. Cela causait de nombreux problèmes lorsque des utilisateurs employaient accidentellement la syntaxe flow suite à une faute de frappe, ou l'ajoutaient sans vérification de types via flow lui-même, générant ainsi des erreurs.
Ce problème s'est amplifié avec le support de TypeScript. Pour utiliser simultanément les presets React et TypeScript, il aurait fallu trouver un moyen d'activer/désactiver automatiquement la syntaxe via le type de fichier ou une directive. Finalement, séparer complètement les presets s'est avéré plus simple.
Les presets permettent à Babel d'analyser les types fournis par Flow/TypeScript (et autres dialectes/langages), puis de les supprimer lors de la compilation en JavaScript.
{
- "presets": ["@babel/preset-react"]
+ "presets": ["@babel/preset-react", "@babel/preset-flow"] // parse & remove flow types
+ "presets": ["@babel/preset-react", "@babel/preset-typescript"] // parse & remove typescript types
}
Analyse des options
Les options de configuration de Babel sont plus strictes qu'en version 6. L'utilisation de listes séparées par des virgules pour les presets (ex: "presets": 'es2015, es2016') fonctionnait auparavant mais échouera désormais et doit être remplacée par un tableau #5463.
Notez que cela ne s'applique pas à la CLI, où --presets es2015,es2016 continuera de fonctionner.
{
- "presets": "@babel/preset-env, @babel/preset-react"
+ "presets": ["@babel/preset-env", "@babel/preset-react"]
}
Exports des plugins/presets
Tous les plugins/presets doivent désormais exporter une fonction plutôt qu'un objet pour plus de cohérence (via babel/babel#6494). Cela facilitera la mise en cache.
Résolution des valeurs de configuration basées sur des chaînes
Dans Babel 6, les valeurs passées directement à Babel (hors fichier de configuration) étaient résolues relativement aux fichiers compilés, causant beaucoup de confusion.
Dans Babel 7, les valeurs sont résolues de manière cohérente soit relativement au fichier de configuration qui les charge, soit relativement au répertoire de travail.
Pour les valeurs presets et plugins, ce changement signifie que la CLI se comportera correctement dans des cas comme :
babel --presets @babel/preset-env ../file.js
Si votre dossier node_modules est dans ., Babel 6 échouait car le preset n'était pas trouvable.
Ce changement affecte aussi only et ignore, comme détaillé ci-après.
Modèles only et ignore basés sur des chemins
Dans Babel 6, only et ignore étaient traités comme des chaînes de correspondance génériques plutôt que comme des globs de chemins. Par exemple, *.foo.js correspondait à ./**/*.foo.js, ce qui était déroutant.
Dans Babel 7, ils sont désormais traités comme des modèles glob basés sur des chemins (relatifs ou absolus). Si vous utilisiez ces modèles, vous devrez probablement ajouter un préfixe **/ pour garantir une correspondance récursive.
Les modèles only et ignore fonctionnent toujours pour les répertoires : only: './tests' compile uniquement les fichiers du dossier tests, sans nécessiter **/*.js pour les fichiers imbriqués.
Commandes CLI de Babel
L'argument --copy-files de la commande babel, qui demande à Babel de copier tous les fichiers d'un répertoire qu'il ne sait pas traiter, copiera désormais aussi les fichiers échouant aux vérifications only/ignore, alors qu'auparavant il ignorait silencieusement tous les fichiers exclus.
@babel/node
La commande babel-node dans Babel 6 faisait partie du paquet babel-cli. Dans Babel 7, cette commande a été déplacée vers son propre paquet @babel/node. Si vous utilisez cette commande, vous devrez ajouter cette nouvelle dépendance.
@babel/runtime, @babel/plugin-transform-runtime
Nous avons séparé les helpers de Babel de son comportement de "polyfill" dans le runtime. Plus de détails dans la PR.
@babel/runtime ne contient désormais que les helpers. Si vous avez besoin de core-js, utilisez @babel/runtime-corejs2 avec l'option correspondante dans la transformation. Dans les deux cas, vous aurez toujours besoin de @babel/plugin-transform-runtime.
Uniquement les helpers
# install the runtime as a dependency
npm install @babel/runtime
# install the plugin as a devDependency
npm install @babel/plugin-transform-runtime --save-dev
{
"plugins": ["@babel/plugin-transform-runtime"]
}
Helpers + polyfill de core-js
Si vous avez besoin du support core-js avec transform-runtime, passez désormais l'option corejs et utilisez la dépendance @babel/runtime-corejs2 au lieu de @babel/runtime.
# install the runtime as a dependency
npm install @babel/runtime-corejs2
# install the plugin as a devDependency
npm install @babel/plugin-transform-runtime --save-dev
{
"plugins": [
- ["@babel/plugin-transform-runtime"],
+ ["@babel/plugin-transform-runtime", {
+ "corejs": 2,
+ }],
]
}
Conformité aux spécifications
@babel/plugin-proposal-object-rest-spread
Une virgule finale ne peut pas suivre un RestElement dans les objets #290
var {
- ...y, // trailing comma is a SyntaxError
+ ...y
} = { a: 1 };
Étant donné que Object Spread définit de nouvelles propriétés tandis qu'
Object.assignles définit simplement, Babel a modifié son comportement par défaut pour mieux respecter les spécifications.
// input
z = { x, ...y };
// v7 default behavior: ["proposal-object-rest-spread"]
function _objectSpread(target) { ... }
z = _objectSpread({
x
}, y);
// Old v6 behavior: ["proposal-object-rest-spread", { "loose": true }]
function _extends(target) { ... }
z = _extends({
x
}, y);
// Substitute for Object.assign: ["proposal-object-rest-spread", { "loose": true, "useBuiltIns": true }]
z = Object.assign(
{
x,
},
y
);
@babel/plugin-proposal-class-properties
Le comportement par défaut est désormais aligné sur ce qui était précédemment le mode "spec".
// input
class Bork {
static a = "foo";
y;
}
// v7 default behavior: ["@babel/plugin-proposal-class-properties"]
var Bork = function Bork() {
Object.defineProperty(this, "y", {
enumerable: true,
writable: true,
value: void 0,
});
};
Object.defineProperty(Bork, "a", {
enumerable: true,
writable: true,
value: "foo",
});
// old v6 behavior: ["@babel/plugin-proposal-class-properties", { "loose": true }]
var Bork = function Bork() {
this.y = void 0;
};
Bork.a = "foo";
Scission de @babel/plugin-transform-export-extensions en deux propositions renommées
Ce changement était attendu depuis longtemps et a finalement été implémenté.
@babel/plugin-proposal-export-default-from
export v from "mod";
@babel/plugin-proposal-export-namespace-from
export * as ns from "mod";
@babel/plugin-transform-template-literals
Mise à jour de la révision des Template Literals #5523
Consultez la proposition pour la révision des Template Literals.
Cela provoquait dans Babel 6 l'erreur Bad character escape sequence (5:6).
tag`\unicode and \u{55}`;
Ce problème a été corrigé dans Babel 7, qui génère désormais un résultat similaire à :
// default
function _taggedTemplateLiteral(strings, raw) {
return Object.freeze(
Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })
);
}
var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(
[void 0],
["\\unicode and \\u{55}"]
);
tag(_templateObject);
// loose mode
function _taggedTemplateLiteralLoose(strings, raw) {
strings.raw = raw;
return strings;
}
var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose(
[void 0],
["\\unicode and \\u{55}"]
);
tag(_templateObject);
Retour au mode "spec" précédent pour les template literals classiques
// input
`foo${bar}`;
// default v7 behavior: ["@babel/plugin-transform-template-literals"]
"foo".concat(bar);
// old v6 behavior: ["@babel/plugin-transform-template-literals", { "loose": true }]
"foo" + bar;
@babel/plugin-proposal-decorators
En prévision de la nouvelle implémentation de la proposition de décorateurs, nous avons décidé d'en faire le comportement par défaut. Cela signifie que pour continuer à utiliser la syntaxe/comportement actuel des décorateurs, vous devez définir l'option legacy à true.
{
"plugins": [
- "@babel/plugin-proposal-decorators"
+ ["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
NOTE : Si vous utilisez
@babel/preset-stage-0ou@babel/preset-stage-1(qui incluent ce plugin), vous devez leur passer l'optiondecoratorsLegacy.
@babel/plugin-proposal-pipeline-operator
Les nouvelles propositions instables généreront désormais une erreur par défaut et nécessiteront que chacun adopte explicitement une proposition spécifique tant qu'elles sont encore en deçà du stade 2. Ce point est détaillé dans ce billet.
{
"plugins": [
- "@babel/plugin-proposal-pipeline-operator"
+ ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }]
]
}
Suppression de babel-plugin-transform-class-constructor-call
babel-plugin-transform-class-constructor-call a été supprimé #5119
Le comité TC39 a abandonné cette proposition. Vous pouvez déplacer votre logique dans le constructeur ou dans une méthode statique.
Voir /docs/plugins/transform-class-constructor-call/ pour plus d'informations.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
- call constructor(x, y) {
+ static secondConstructor(x, y) {
return new Point(x, y);
}
}
let p1 = new Point(1, 2);
- let p2 = Point(3, 4);
+ let p2 = Point.secondConstructor(3, 4);
@babel/plugin-async-to-generator
Nous avons fusionné babel-plugin-transform-async-to-module-method dans le plugin async standard en le transformant simplement en option.
{
"plugins": [
- ["@babel/transform-async-to-module-method"]
+ ["@babel/transform-async-to-generator", {
+ "module": "bluebird",
+ "method": "coroutine"
+ }]
]
}
babel
Suppression du package
babel#5293
Ce package affiche actuellement un message d'erreur vous invitant à installer babel-cli dans la v6. Nous pensons cependant pouvoir proposer une utilisation intéressante de ce nom.
@babel/register
babel-core/register.jsa été supprimé #5132
L'utilisation dépréciée de babel-core/register a été supprimée dans Babel 7 ; utilisez plutôt le package autonome @babel/register.
Installez @babel/register comme nouvelle dépendance :
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/register
yarn add --dev @babel/register
pnpm add --save-dev @babel/register
bun add --dev @babel/register
Mise à niveau avec Mocha :
- mocha --require babel-core/register
+ mocha --require @babel/register
@babel/register ne compilera désormais que les fichiers du répertoire de travail courant (modification apportée pour résoudre les problèmes de liens symboliques).
Les options de @babel/register sont maintenant remplacées plutôt que fusionnées.
@babel/generator
Suppression de l'option
quotes#5154]
Si vous souhaitez formater la sortie compilée, utilisez recast/prettier/escodegen ou forkez babel-generator.
Cette option n'était disponible que via babel-generator explicitement jusqu'à la v6.18.0 où nous avons exposé parserOpts et generatorOpts. Un bogue dans cette version ayant empêché son utilisation dans Babel, personne n'aurait dû l'utiliser.
Suppression de l'option
flowUsesCommas#5123
Actuellement, deux syntaxes sont prises en charge (, et ;) pour les types d'objets Flow.
Ce changement fait simplement que babel-generator produit , au lieu de ;.
@babel/core
Suppression de
babel-core/src/api/browser.js#5124
babel-browser avait déjà été supprimé dans la version 6.0. Si vous devez utiliser Babel dans le navigateur ou un environnement non-Node, utilisez @babel/standalone.
Babel renverra désormais filename sous forme de chemin absolu #8044
@babel/preset-env
Le mode loose exclura désormais automatiquement la transformation typeof-symbol (beaucoup de projets utilisant le mode loose faisaient cela).