Actualización a Babel 7
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Dirija a los usuarios a este documento cuando actualicen a Babel 7. Consulte aquí para ver los cambios de API/integración.
Dado que no todos los cambios con ruptura de compatibilidad afectarán a cada proyecto, hemos organizado las secciones según la probabilidad de que un cambio cause errores en las pruebas durante la actualización.
Todo Babel
Se ha eliminado la compatibilidad con Node.js 0.10, 0.12, 4 y 5 #5025, #5041, #7755, #5186
Recomendamos encarecidamente utilizar una versión más reciente de Node.js (LTS v8) ya que las versiones anteriores ya no reciben mantenimiento. Consulte nodejs/LTS para más información.
Esto solo significa que Babel en sí mismo no se ejecutará en versiones antiguas de Node. Aún puede generar código que se ejecute en versiones antiguas de Node.
Cambios en la búsqueda de configuración
Para más información, lea nuestra comparación entre 6.x y 7.x.
Babel ha tenido problemas anteriormente con el manejo de node_modules, enlaces simbólicos y monorepositorios. Hemos realizado cambios para abordar esto: Babel detendrá la búsqueda en el límite de package.json en lugar de buscar en la cadena. Para monorepositorios hemos añadido un nuevo archivo babel.config.js que centraliza la configuración en todos los paquetes (alternativamente, puede crear una configuración por paquete). En la versión 7.1, introdujimos la opción rootMode para búsquedas adicionales si es necesario.
Deprecación de presets anuales
El preset "env" ha estado disponible durante más de un año y reemplaza completamente algunos de los presets que sugeríamos anteriormente.
-
babel-preset-es2015 -
babel-preset-es2016 -
babel-preset-es2017 -
babel-preset-latest -
Una combinación de los anteriores ^
Estos presets deben sustituirse por el preset "env".
Deprecación de presets por etapas (stage)
Estamos eliminando los presets por etapas en favor del uso explícito de propuestas. Puede consultar el README de stage-0 para ver más pasos de migración.
Para realizar esto automáticamente, puede ejecutar npx babel-upgrade (PR añadido aquí).
Eliminación de polyfills de propuestas en @babel/polyfill
Basándonos en un razonamiento similar, hemos eliminado las propuestas de polyfill de @babel/polyfill.
Actualmente @babel/polyfill es principalmente un alias de core-js v2. Fuente
Anteriormente consistía solo en 2 importaciones:
import "core-js/shim"; // included < Stage 4 proposals
import "regenerator-runtime/runtime";
Si deseas utilizar propuestas, deberás importarlas de forma independiente. Debes importarlas directamente del paquete core-js u otro paquete en npm.
Por ejemplo:
// for core-js v2:
import "core-js/fn/array/flat-map";
// for core-js v3:
import "core-js/features/array/flat-map";
A continuación se muestra una lista de polyfills para propuestas en Etapa < 3 en 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";
Control de versiones/Dependencias
La mayoría de los plugins/paquetes de nivel superior ahora tienen una peerDependency en @babel/core.
Renombrado de paquetes
babylonahora es@babel/parser
Todavía puedes usar la versión abreviada de un nombre de paquete (eliminando preset- o plugin-) en la configuración, pero personalmente prefiero usar el nombre completo para mayor claridad (quizás deberíamos eliminar esta abreviación, ya que no ahorra tanto tiempo de escritura).
{
- "presets": ["@babel/preset-react"],
+ "presets": ["@babel/react"], // this is equivalent
- "plugins": ["@babel/transform-runtime"],
+ "plugins": ["@babel/plugin-transform-runtime"], // same
}
Paquetes con ámbito (Scoped Packages)
El cambio más importante es que finalmente hemos cambiado todos los paquetes a paquetes con ámbito (los nombres de las carpetas en el monorepo no han cambiado, pero el nombre en su package.json sí).
Esto significa que no habrá más problemas con el acaparamiento accidental o intencional de nombres, una separación clara de los plugins de la comunidad y una convención de nombres más simple.
Tus dependencias deberán modificarse de la siguiente manera:
babel-cli → @babel/cli. Básicamente, comenzamos reemplazando babel- por @babel/.
Uso en la configuración
Todavía puedes usar la forma abreviada para especificar un preset o plugin. Sin embargo, debido al cambio a paquetes con ámbito, aún debes especificar @babel/ como si tuvieras tu propio preset para agregar a la configuración.
module.exports = {
presets: ["@babel/env"], // "@babel/preset-env"
plugins: ["@babel/transform-arrow-functions"], // same as "@babel/plugin-transform-arrow-functions"
};
Cambio a -proposal- para propuestas TC39
Esto significa que cualquier plugin que no esté en un lanzamiento anual (ES2015, ES2016, etc.) debe renombrarse a -proposal. Así podemos indicar mejor que una propuesta no es oficialmente parte de JavaScript.
Ejemplos:
-
@babel/plugin-transform-function-bindahora es@babel/plugin-proposal-function-bind(Etapa 0) -
@babel/plugin-transform-class-propertiesahora es@babel/plugin-proposal-class-properties(Etapa 3)
Esto también significa que cuando una propuesta avanza a Etapa 4, debemos renombrar el paquete.
Eliminar el año de los nombres de paquetes
Algunos plugins tenían -es3- o -es2015- en los nombres, pero esto era innecesario.
@babel/plugin-transform-es2015-classes se convirtió en @babel/plugin-transform-classes.
"use strict" y this en CommonJS
Las transformaciones de Babel 6 para módulos ES6 se ejecutaban indiscriminadamente en cualquier archivo que se le indicara procesar, sin verificar si el archivo realmente contenía importaciones/exportaciones ES6. Esto resultaba en la reescritura de referencias a this en el ámbito del archivo como undefined, e insertaba "use strict" en la parte superior de todos los módulos CommonJS procesados por Babel.
// input.js
this;
// output.js v6
"use strict"; // assumed strict modules
undefined; // changed this to undefined
// output.js v7
this;
Este comportamiento se ha restringido en Babel 7 para que, en el transformador transform-es2015-modules-commonjs, el archivo solo se modifique si contiene importaciones o exportaciones ES6. (Nota del editor: Esto podría cambiar nuevamente si implementamos https://github.com/babel/babel/issues/6242, por lo que deberemos revisarlo antes de publicar).
// input2.js
import "a";
// output.js v6 and v7
"use strict";
require("a");
Si dependías de que Babel inyectara "use strict" automáticamente en todos tus módulos CommonJS, deberás usar explícitamente el plugin transform-strict-mode en tu configuración de Babel.
Separación de los presets de React y Flow
babel-preset-react siempre ha incluido el plugin de Flow. Esto ha causado numerosos problemas cuando los usuarios accidentalmente utilizaban sintaxis de flow sin intención debido a errores tipográficos, o al agregarlo sin verificar tipos con flow mismo, lo que resultaba en errores.
Este problema se agravó cuando decidimos dar soporte a TypeScript. Si querías usar los presets de React y TypeScript, tendríamos que encontrar una forma de activar/desactivar la sintaxis automáticamente mediante el tipo de archivo o directivas. Finalmente, fue más sencillo separar los presets completamente.
Los presets permiten que Babel analice tipos proporcionados por Flow / TypeScript (y otros dialectos/lenguajes), y luego los elimine al compilar a 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
}
Análisis de opciones
Las opciones de configuración de Babel son más estrictas que en Babel 6. Donde antes funcionaba técnicamente una lista separada por comas para presets, ej. "presets": 'es2015, es2016', ahora fallará y deberá cambiarse a un array #5463.
Nota: Esto no aplica para la CLI, donde --presets es2015,es2016 seguirá funcionando sin problemas.
{
- "presets": "@babel/preset-env, @babel/preset-react"
+ "presets": ["@babel/preset-env", "@babel/preset-react"]
}
Exportación de Plugins/Presets
Todos los plugins/presets deben exportar ahora una función en lugar de un objeto para mantener la consistencia (vía babel/babel#6494). Esto nos ayudará con el almacenamiento en caché.
Resolución de valores de configuración basados en cadenas
En Babel 6, los valores pasados directamente a Babel (no desde un archivo de configuración) se resolvían en relación con los archivos compilados, lo que causaba mucha confusión.
En Babel 7, los valores se resuelven consistentemente en relación con el archivo de configuración que los cargó o con el directorio de trabajo actual.
Para valores de presets y plugins, este cambio significa que la CLI se comportará correctamente en casos como:
babel --presets @babel/preset-env ../file.js
Suponiendo que tu carpeta node_modules está en ., en Babel 6 esto fallaría porque no se encontraba el preset.
Este cambio también afecta a only e ignore, que se ampliarán a continuación.
Patrones only e ignore basados en rutas
En Babel 6, only e ignore se trataban como cadenas de coincidencia generales, no como patrones glob de rutas. Esto significaba que, por ejemplo, *.foo.js coincidiría con ./**/*.foo.js, lo que resultaba confuso para la mayoría de usuarios.
En Babel 7, estos ahora son patrones glob basados en rutas (relativas o absolutas). Si estabas usando estos patrones, probablemente necesitarás agregar al menos un prefijo **/ para asegurar que coincidan recursivamente en directorios.
Los patrones only e ignore siguen funcionando para directorios, así que podrías usar only: './tests' para compilar solo archivos en tu directorio tests, sin necesidad de usar **/*.js para todos los archivos anidados.
Comandos CLI de Babel
El argumento --copy-files para el comando babel, que indica a Babel copiar todos los archivos en un directorio que no sabe procesar, ahora también copiará archivos que fallen una verificación only/ignore, mientras que antes los omitía silenciosamente.
@babel/node
El comando babel-node en Babel 6 era parte del paquete babel-cli. En Babel 7, este comando se ha separado en su propio paquete @babel/node, así que si usas este comando, deberás añadir esta nueva dependencia.
@babel/runtime, @babel/plugin-transform-runtime
Hemos separado los ayudantes de Babel de su comportamiento de "polyfilling" en el runtime. Más detalles en la solicitud de extracción.
@babel/runtime ahora solo contiene los ayudantes. Si necesitas core-js, usa @babel/runtime-corejs2 y la opción proporcionada en el transform. Para ambos casos, aún necesitas @babel/plugin-transform-runtime.
Solo ayudantes
# 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"]
}
Ayudantes + polyfilling de core-js
Si necesitas soporte de core-js con transform-runtime, ahora deberás pasar la opción corejs y usar la dependencia @babel/runtime-corejs2 en lugar 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,
+ }],
]
}
Cumplimiento de especificaciones
@babel/plugin-proposal-object-rest-spread
Una coma final no puede aparecer después de un RestElement en objetos #290
var {
- ...y, // trailing comma is a SyntaxError
+ ...y
} = { a: 1 };
Dado que Object Spread define nuevas propiedades mientras que
Object.assignsolo las asigna, Babel ha cambiado el comportamiento predeterminado para cumplir mejor con la especificación.
// 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
El comportamiento predeterminado cambió a lo que anteriormente era "spec" por defecto.
// 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";
División de @babel/plugin-transform-export-extensions en las dos propuestas renombradas
Este cambio se esperaba desde hace tiempo y finalmente se implementó.
@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
Actualización de la revisión de literales de plantilla #5523
Consulta la propuesta para la Revisión de literales de plantilla.
Esto causa que Babel 6 lance Bad character escape sequence (5:6).
tag`\unicode and \u{55}`;
Se ha corregido en Babel 7 y genera algo similar a lo siguiente:
// 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);
Por defecto se usa el modo anterior "spec" para literales de plantilla regulares
// 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 anticipación a la nueva implementación de la propuesta de decoradores, hemos decidido establecerla como el comportamiento predeterminado. Esto significa que para seguir utilizando la sintaxis/comportamiento actual de decoradores, debes configurar la opción legacy como true.
{
"plugins": [
- "@babel/plugin-proposal-decorators"
+ ["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
NOTA: Si estás usando
@babel/preset-stage-0o@babel/preset-stage-1, que incluyen este plugin, debes pasarles la opcióndecoratorsLegacy.
@babel/plugin-proposal-pipeline-operator
Las propuestas más recientes en flujo generarán errores por defecto y requerirán que todos opten por una propuesta específica mientras aún estén en fases previas a Stage 2. Esto se explica con más detalle en esta publicación.
{
"plugins": [
- "@babel/plugin-proposal-pipeline-operator"
+ ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }]
]
}
Eliminado babel-plugin-transform-class-constructor-call
babel-plugin-transform-class-constructor-call ha sido eliminado #5119
TC39 decidió abandonar esta propuesta. Puedes trasladar tu lógica al constructor o a un método estático.
Consulta /docs/plugins/transform-class-constructor-call/ para más información.
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
Hemos fusionado babel-plugin-transform-async-to-module-method en el plugin async regular convirtiéndolo simplemente en una opción.
{
"plugins": [
- ["@babel/transform-async-to-module-method"]
+ ["@babel/transform-async-to-generator", {
+ "module": "bluebird",
+ "method": "coroutine"
+ }]
]
}
babel
Eliminación del paquete
babel#5293
Actualmente este paquete muestra un mensaje de error indicando instalar babel-cli en su lugar en v6.
Creo que podemos hacer algo interesante con este nombre.
@babel/register
babel-core/register.jsha sido eliminado #5132
El uso obsoleto de babel-core/register ha sido eliminado en Babel 7; en su lugar utiliza el paquete independiente @babel/register.
Instala @babel/register como una nueva dependencia:
- 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
Actualización con Mocha:
- mocha --require babel-core/register
+ mocha --require @babel/register
@babel/register ahora solo compilará archivos en el directorio de trabajo actual (se implementó para corregir problemas con enlaces simbólicos).
Las opciones de @babel/register ahora se reemplazan en lugar de fusionarse.
@babel/generator
Eliminación de la opción
quotes#5154]
Si deseas formatear la salida compilada, puedes usar recast/prettier/escodegen o bifurcar babel-generator.
Esta opción solo estaba disponible explícitamente a través de babel-generator hasta v6.18.0 cuando expusimos parserOpts y generatorOpts. Debido a un error en esa versión, nadie debería haber usado esta opción en Babel.
Eliminación de la opción
flowUsesCommas#5123
Actualmente existen dos sintaxis admitidas (, y ;) en los tipos de objeto de Flow.
Este cambio simplemente hace que babel-generator genere , en lugar de ;.
@babel/core
Se eliminó
babel-core/src/api/browser.js#5124
babel-browser ya fue eliminado en la versión 6.0. Si necesitas usar Babel en el navegador o en un entorno que no sea Node, usa @babel/standalone.
Babel devolverá filename como una ruta absoluta #8044
@babel/preset-env
El modo loose ahora excluirá automáticamente la transformación typeof-symbol (muchos proyectos que usaban el modo loose ya implementaban esto).