Suposiciones del compilador
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Por defecto, Babel intenta compilar tu código para que coincida con el comportamiento nativo lo más fielmente posible. Sin embargo, esto a veces implica generar más código de salida o un código más lento, solo para soportar algunos casos extremos que no te interesan.
Desde Babel 7.13.0, puedes especificar una opción assumptions en tu configuración para indicarle a Babel qué suposiciones puede hacer sobre tu código, optimizando así mejor el resultado de la compilación. Nota: esto reemplaza las diversas opciones loose en los plugins en favor de opciones de alto nivel aplicables a múltiples plugins (enlace al RFC).
Por ejemplo:
{
"targets": ">0.5%",
"assumptions": {
"noDocumentAll": true,
"noClassCalls": true
},
"presets": ["@babel/preset-env"]
}
Esta es una funcionalidad avanzada. Ten cuidado al habilitar suposiciones, ya que no cumplen con las especificaciones y podrían romper tu código de formas inesperadas.
¿Estás migrando desde las opciones loose y spec de @babel/preset-env hacia suposiciones granulares? Consulta "Migrando desde los modos "loose" y "spec" de @babel/preset-env" para obtener la configuración equivalente basada en suposiciones, lista para copiar y pegar como punto de partida.
arrayLikeIsIterable
Al expandir o iterar un objeto tipo array, supone que implementa un método [Symbol.iterator] con el mismo comportamiento que el nativo Array.prototype[Symbol.iterator], iterando así directamente sus elementos por índice.
Esto puede ser útil, por ejemplo, para iterar colecciones DOM en navegadores antiguos.
let images = $("img");
for (const img of images) {
console.log(img);
}
const copy = [...images];
constantReexports
Al reexportar un binding desde un módulo, supone que no cambia y por tanto es seguro exportarlo directamente, como si hicieras:
import { value as val } from "dep";
export const value = val;
NOTA: Esto también afecta a los plugins transform-modules-umd y transform-modules-amd.
export { value } from "dependency";
constantSuper
La superclase de una clase puede cambiarse en cualquier momento usando Object.setPrototypeOf, imposibilitando que Babel la conozca estáticamente. Al habilitar esta opción, Babel asume que nunca cambia y por tanto siempre será el valor declarado en la cláusula extends.
class Child extends Base {
method() {
super.method(2);
}
}
enumerableModuleMeta
Al compilar ESM a CJS, Babel define una propiedad __esModule en el objeto module.exports. Supone que nunca iteras sobre las claves de module.exports o de require("your-module") usando for..in u Object.keys, por lo que es seguro definir __esModule como enumerable.
export const number = 2;
ignoreFunctionLength
Las funciones tienen una propiedad .length que refleja el número de parámetros hasta el último no predeterminado. Al habilitar esta opción, supone que el código compilado no depende de esta propiedad .length.
function fn(a, b = 2, c, d = 3) {
return a + b + c + d;
}
ignoreToPrimitiveHint
Al usar características del lenguaje que puedan invocar el método [Symbol.toPrimitive] de objetos, supone que no cambian su comportamiento según el parámetro hint.
let str = `a${foo}b`;
iterableIsArray
Al usar un objeto iterable (en destructuración de arrays, bucles for-of o spreads), supone que es un array.
const [first, ...rest] = obj;
call(first, ...obj);
let arr = [first, ...obj];
for (const el of obj) {
console.log(el);
}
mutableTemplateObject
No usa Object.freeze para el objeto plantilla creado en literales de plantilla etiquetados. Esto significa usar el helper taggedTemplateLiteralLoose en lugar de taggedTemplateLiteral.
let str = tag`a`;
noClassCalls
Al transformar clases, supone que siempre se instancian con new y nunca se invocan como funciones.
class Test {
constructor() {
this.x = 2;
}
}
noDocumentAll
Al usar operadores que verifican null o undefined, asume que nunca se utilizan con el valor especial document.all.
let score = points ?? 0;
let name = user?.name;
noIncompleteNsImportDetection
Asume que no se observa ninguna propiedad propia de un objeto de exportación de módulo antes de su inicialización.
Por ejemplo, al intentar acceder a ns.foo, devolverá undefined tanto con esta suposición activada como desactivada. La
diferencia es que Object.prototype.hasOwnProperty.call(ns, "foo") devolvería false cuando
noIncompleteNsImportDetection: true.
export var foo;
noNewArrows
Asume que el código nunca intenta instanciar funciones flecha usando new, lo cual está prohibido según la especificación.
NOTA: Esta suposición tiene como valor predeterminado true. A partir de Babel 8, el valor predeterminado será false.
let getSum = (a, b) => {
return { sum: a + b }
};
noUninitializedPrivateFieldAccess
History
| Version | Changes |
|---|---|
| v7.24.0 | Added noUninitializedPrivateFieldAccess assumption |
Asume que el código nunca intenta acceder a campos privados en clases antes de que estén inicializados. Por ejemplo:
class Foo {
x = this.#y; // #y is not initialized yet
#y = 2;
}
class MyClass {
static #id = 123;
method() {
return MyClass.#id;
}
}
objectRestNoSymbols
Al usar patrones de rest en desestructuración de objetos, asume que los objetos desestructurados no tienen claves de símbolo o que no es problema si no se copian.
let { name, ...attrs } = obj;
privateFieldsAsProperties
Asume que la "privacidad débil" es suficiente para campos privados, por lo que pueden almacenarse como propiedades públicas no enumerables con un nombre único (en lugar de usar un WeakMap externo). Esto facilita la depuración de campos privados compilados.
class Foo {
#method() {}
#field = 2;
run() {
this.#method();
this.#field++;
}
}
Al usar helpers de Babel en línea, las claves de cadena generadas son únicas por archivo, no globalmente. Esto podría causar conflictos al extender clases de diferentes archivos con campos privados del mismo nombre.
privateFieldsAsSymbols
History
| Version | Changes |
|---|---|
| v7.21.0 | Added privateFieldsAsSymbols assumption |
Asume que la "privacidad débil" es suficiente para campos privados, por lo que pueden almacenarse como propiedades públicas con una clave de símbolo (en lugar de usar un WeakMap externo). Esto facilita la depuración de campos privados compilados.
class Foo {
#method() {}
#field = 2;
run() {
this.#method();
this.#field++;
}
}
pureGetters
Asume que los getters, si existen, no tienen efectos secundarios y pueden accederse múltiples veces.
let a = obj;
a.b?.();
setClassMethods
Al declarar clases, asume que los métodos no ocultan accesores o propiedades no escribibles en el prototipo de la superclase, y que el programa no depende de que los métodos sean no enumerables. Por tanto, es seguro asignar métodos en lugar de usar Object.defineProperty.
class Foo extends Bar {
method() {}
static check() {}
}
setComputedProperties
Al usar propiedades computadas en objetos, asume que el objeto no contiene propiedades que sobrescriban setters definidos en el mismo objeto, por lo que es seguro asignarlas en lugar de definirlas con Object.defineProperty.
let obj = {
set name(value) {},
[key]: val
}
setPublicClassFields
Al usar campos públicos de clase, asume que no ocultan ningún getter en la clase actual, sus subclases o su superclase. Por tanto, es seguro asignarlos en lugar de usar Object.defineProperty.
class Test {
field = 2;
static staticField = 3;
}
setSpreadProperties
Al usar spread de objetos, asume que las propiedades esparcidas no activan getters en el objeto destino, por lo que es seguro asignarlas en lugar de definirlas con Object.defineProperty.
const result = {
set name(value) {},
...obj,
};
skipForOfIteratorClosing
Al usar for-of con un iterador, este siempre debería cerrarse con .return() y con .throw() en caso de error. Cuando esta opción está activada, Babel asume que esos métodos no están definidos o están vacíos, y evita llamarlos.
for (const val of iterable) {
console.log(val);
}
superIsCallableConstructor
Al extender clases, asume que la superclase es invocable. Esto significa que no será posible extender clases nativas o built-ins, solo clases compiladas o constructores ES5 de tipo function.
class Child extends Parent {
constructor() {
super(42);
}
}
Migrando desde los modos "loose" y "spec" de @babel/preset-env
La opción loose de @babel/preset-env es equivalente a la siguiente configuración:
{
"presets": [
["@babel/preset-env", { "exclude": ["transform-typeof-symbol"] }]
],
"assumptions": {
"arrayLikeIsIterable": true,
"constantReexports": true,
"ignoreFunctionLength": true,
"ignoreToPrimitiveHint": true,
"mutableTemplateObject": true,
"noClassCalls": true,
"noDocumentAll": true,
"objectRestNoSymbols": true,
"privateFieldsAsProperties": true,
"pureGetters": true,
"setClassMethods": true,
"setComputedProperties": true,
"setPublicClassFields": true,
"setSpreadProperties": true,
"skipForOfIteratorClosing": true,
"superIsCallableConstructor": true
}
}
La opción spec de @babel/preset-env es equivalente a la siguiente configuración:
{
"presets": ["@babel/preset-env"],
"assumptions": {
"noNewArrows": false,
}
}