Actualización a Babel 7 (API)
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Dirige a los usuarios a este documento cuando actualicen a Babel 7.
También consulta la guía de migración a v7 para otros cambios a nivel de usuario.
Todos los paquetes de Babel
Soporte para NodeJS
Se ha eliminado el soporte para Node.js 0.10 y 0.12 ya que ambas versiones están fuera de mantenimiento.
Cambios en las exportaciones
Se eliminó el uso del plugin add-module-exports en los paquetes de Babel.
Este se utilizaba anteriormente para evitar un cambio incompatible en nuestras exportaciones.
Si importas un paquete de Babel en una biblioteca, es posible que necesites usar .default cuando utilices require en lugar de import.
@babel/core
Se cambió ast a false por defecto por rendimiento (la mayoría de herramientas no lo usan) babel/babel#7436.
Se eliminó la clase Pipeline (expuesta públicamente pero no documentada). Es mejor usar los métodos de transformación expuestos directamente por @babel/core babel/babel#5376.
Se eliminaron los métodos auxiliares babel.util.*, y util.EXTENSIONS se movió a babel.DEFAULT_EXTENSIONS babel/babel#5487.
Las llamadas a babel.transform o cualquier otra función de transformación pueden devolver null si el archivo coincide con un patrón ignore o no coincide con un patrón only babel/babel#5487.
Se eliminó la opción opts.basename expuesta en state.file.opts. Si la necesitas, es mejor que la construyas tú mismo a partir de opts.filename babel/babel#5467.
Se eliminó resolveModuleSource. Recomendamos usar la opción 'resolvePath' de babel-plugin-module-resolver@3 babel/babel#6343
Se eliminó babel.analyse porque solo era un alias de babel.transform
Se eliminó path.mark() ya que no lo usábamos y se puede implementar en tu propio plugin.
Se eliminó babel.metadata ya que los metadatos del plugin generado siempre se incluyen en el resultado de salida.
Se eliminó path.hub.file.addImport. Puedes usar el módulo @babel/helper-module-imports en su lugar.
+ 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 });
}
Cambios en la configuración
Hemos realizado cambios importantes en cómo funciona la búsqueda de configuración:
Por defecto, al buscar archivos
.babelrcpara un archivo dado, se detiene enpackage.json.
Para cualquier archivo específico, Babel v6 sigue buscando en la jerarquía de directorios hasta encontrar un archivo de configuración. Esto significa que tu proyecto podría romperse si utiliza un archivo de configuración encontrado fuera de la raíz del paquete, como en el directorio home.
Se añade soporte para un archivo
babel.config.jssimilar a lo que hace Webpack
Dado que esto rompería el funcionamiento de un monorepo (incluido el propio Babel), estamos introduciendo un nuevo archivo de configuración que básicamente elimina la naturaleza jerárquica de las configuraciones.
Se incluye una opción root que por defecto es el directorio de trabajo actual para localizar el archivo. Además, no se carga relativamente, por lo que manejará correctamente los symlinks, mientras que antes podrías haber tenido que codificar rígidamente las rutas en webpack.
Consulta la documentación de babel.config.js para más información: configuración para todo el proyecto
Este archivo combinado con la nueva propiedad overrides y env te permite tener un único archivo de configuración que funcione para todos los archivos de un proyecto, a diferencia de múltiples archivos de configuración por carpeta.
También excluimos node_modules por defecto y solo buscamos en la raíz, a menos que optes por configurar un array de la opción .babelrcRoots como "babelrcRoots": [".", "node_modules/pkgA"]
Verificación de la versión de Babel #7450
Los plugins pueden verificar que se carguen con cierta versión de Babel. La API expondrá un método assertVersion, donde puedes pasar una versión semver.
El helper declare se utiliza para mantener compatibilidad con versiones anteriores (v6).
import { declare } from "@babel/helper-plugin-utils";
export default declare(api => {
api.assertVersion(7);
// ...
});
Plugins y presets de Babel
Actualmente toma como primer parámetro el objeto babel, las opciones del plugin/preset y el dirname
module.exports = function(api, options, dirname) {};
babel-parser (conocido como Babylon)
Se eliminó la opción de plugin
*#301
Esta opción se agregó inicialmente en v6.14.1 (17 nov 2016), por lo que es poco probable que alguien la estuviera usando.
Esta opción general fue eliminada; en su lugar debes especificar qué plugins quieres activar.
Pensamos que sería útil para herramientas que no tendrían que actualizar constantemente su configuración, pero también significa que no podemos hacer fácilmente cambios con ruptura de compatibilidad.
Antes:
babelParser.parse(code, {
plugins: ["*"],
});
Puedes obtener el comportamiento antiguo usando:
babelParser.parse(code, {
plugins: [
"asyncGenerators",
"classProperties",
"decorators",
"doExpressions",
"dynamicImport",
"exportExtensions",
"flow",
"functionBind",
"functionSent",
"jsx",
"objectRestSpread",
],
});
Consulta las opciones de plugins de Babylon.
Se renombró el plugin
decoratorsadecorators-legacy
Se renombró para alinearse con la opción legacy de @babel/plugin-proposal-decorators. Se implementó un nuevo plugin decorators que sigue la nueva propuesta de decoradores.
Las dos versiones de las propuestas tienen sintaxis diferentes, por lo que se recomienda encarecidamente usar decorators-legacy hasta que Babel implemente las nuevas semánticas.
Se eliminó el plugin
classConstructorCall#291
@babel/traverse
Se eliminó el soporte para bindings de flow babel/babel#6528
Este cambio se debe a que declare var foo no introduce un binding local, sino que representa uno global.
getFunctionParentya no devolveráProgram, usagetProgramParenten su lugar #5923.
No tiene sentido que una función llamada getFunctionParent también devuelva Program, por lo que se eliminó ese comportamiento.
Para obtener el comportamiento equivalente, deberás realizar un cambio como:
- path.scope.getFunctionParent()
+ path.scope.getFunctionParent() || path.scope.getProgramParent()
Las APIs de reemplazo/eliminación de rutas ahora devuelven un array de nuevas rutas
Por ejemplo, usar Path#insertBefore o Path#replaceWith ahora siempre devolverá un array de las rutas recién insertadas/reemplazadas.
const node = t.nullLiteral();
const [replaced] = path.replaceWith(node);
replace.node === node; // => true
Esto es especialmente útil al insertar varios nodos en un ámbito superior, ya que puedes llamar inmediatamente a las APIs Path en la nueva Path del nodo.
const parent = path.findParent(() => /* some selection criteria */);
const helperPaths = path.unshiftContainer("body", helpers);
// helperPaths can now be referenced, manipulated, etc.
Cambios en el AST
Se añade el nodo InterpreterDirective #7928
Babylon ya analizaba "shebangs" (#!env node) pero los colocaba como comentario en el nodo Program. Ahora creamos un nodo específico para ello.
Se añade un nuevo campo interpreter al nodo Program.
extend interface Program {
interpreter: InterpreterDirective;
}
Se añade el nodo InterpreterDirective
interface InterpreterDirective <: Node {
type: "InterpreterDirective";
value: string;
}
Constructores de nodos JSX* y TS* (del paquete @babel/types) renombrados
Se cambió el caso: jsx y ts ahora están en minúsculas.
- t.jSXIdentifier()
+ t.jsxIdentifier()
En general, hemos diferenciado los tipos de nodos con TypeAnnotation para Flow y TSTypeAnnotation para TypeScript, por lo que para los nodos de tipo compartidos, TypeScript tiene prefijo TS.
Campo .expression eliminado de ArrowFunctionExpression
Se eliminó el campo expression para eliminar dos fuentes de verdad distintas y evitar que los plugins tuvieran que sincronizarlas manualmente. Ahora simplemente puedes verificar si el cuerpo de la función es un BlockStatement o no:
return {
visitor: {
ArrowFunctionExpression({ node }) {
- if (node.expression) {
+ if (node.body.type !== "BlockStatement") {
// () => foo;
}
}
}
};
Tokens eliminados
En versiones anteriores, los tokens siempre se adjuntaban al AST en el nivel superior. En la última versión de @babel/parser eliminamos este comportamiento y lo desactivamos por defecto para mejorar el rendimiento. Todos los usos en Babel mismo se han eliminado y @babel/generator ya no usa tokens para el formateo.
Si tu plugin de Babel usa tokens actualmente, evalúa si sigue siendo necesario e intenta eliminar su uso si es posible. Si tu plugin realmente depende de obtener tokens, puedes reactivarlo, pero considera esto solo si no hay otra alternativa, ya que afectará el rendimiento.
Para activarlo, debes establecer la opción tokens de babylon en true. Puedes hacerlo directamente desde tu plugin.
export default function() {
return {
manipulateOptions(opts, parserOpts) {
parserOpts.tokens = true;
},
...
};
}
Renombrados
Los siguientes nodos han sido renombrados:
| Name 6.x | Name 7.x | Example | PR |
|---|---|---|---|
| ExistentialTypeParam | ExistsTypeAnnotation | type A = B<*>; | #322 |
| NumericLiteralTypeAnnotation | NumberLiteralTypeAnnotation | type T = 0; | #332 |
Además de los nodos AST, todas las funciones correspondientes en @babel/types también han sido renombradas.
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();
}
};
Reemplazados
En los siguientes nodos AST, el valor del campo variance ha cambiado de ser un string simple a ser su propio nodo AST llamado Variance. #333
Este campo solo está disponible al activar el plugin flow en babylon.
-
ObjectProperty
-
ObjectMethod
-
AssignmentProperty
-
ClassMethod
-
ClassProperty
-
Property
El tipo del nuevo nodo Variance se ve así:
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") {
...
}
}
};
Cambios de ubicación
La información de ubicación de ObjectTypeIndexer ha cambiado para no incluir punto y coma. Esto se hizo para alinearse con el flow-parser y tener la misma información de ubicación. #228
Ejemplo:
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
}
}
}
Eliminación
ForAwaitStatement
El nodo AST ForAwaitStatement ha sido eliminado y se reemplaza por el campo await en el nodo ForOfStatement #349
interface ForOfStatement <: ForInStatement {
type: "ForOfStatement";
+ await: boolean;
}
return {
- ForAwaitStatement(path) {
- ...
+ ForOfStatement(path) {
+ if (path.node.await) {
+ ...
+ }
}
};
RestProperty y SpreadProperty
Los dos nodos AST RestProperty y SpreadProperty han sido eliminados en favor de reutilizar RestElement y 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()) {
+ ...
+ }
}
};
Consulta nuestro PR de actualización para Babel y la especificación AST de Babylon para más información.