7.14.0 Publicado: Nuevas características de clases habilitadas por defecto, TypeScript 4.3 y mejor interoperabilidad con CommonJS
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
¡Babel 7.14.0 ya está aquí!
Esta versión habilita los campos de clase y métodos privados por defecto (¡promovidos a la Etapa 4 durante la reciente reunión de TC39 en abril!) y añade comprobaciones de marca para campos privados y bloques de clase estáticos a la opción shippedProposals de @babel/preset-env.
Hemos añadido soporte para las expresiones do asíncronas de Etapa 1 (usando @babel/plugin-proposal-async-do-expressions), que extienden la propuesta de expresiones do de Etapa 1.
Gracias a Sosuke Suzuki y Pig Fang, Babel ahora puede manejar las características de TypeScript 4.3. @babel/parser también tiene una nueva opción para analizar correctamente archivos de declaración TypeScript.
Finalmente, hemos introducido una nueva opción importInterop: node para facilitar la producción de módulos duales compilando importaciones de ECMAScript a CommonJS que siguen la semántica de Node.js.
Puedes leer el registro de cambios completo en GitHub.
Si tú o tu empresa quieren apoyar a Babel y la evolución de JavaScript, pero no están seguros de cómo hacerlo, pueden donar a través de nuestro Open Collective y, mejor aún, ¡colaborar directamente con nosotros en la implementación de nuevas propuestas de ECMAScript! Como proyecto impulsado por voluntarios, dependemos del apoyo de la comunidad para financiar nuestros esfuerzos en atender a la amplia variedad de usuarios de JavaScript. Contáctenos en team@babeljs.io si desean discutir más opciones.
Destacados
Nuevas características de clases habilitadas por defecto
¡Las propuestas de campos de clase y métodos privados acaban de alcanzar la Etapa 4 y serán incluidas oficialmente en ECMAScript 2022! Esto fue más una formalidad ya que la semántica ya estaba finalizada y ya se han implementado en todos los navegadores principales.
Puedes leer más detalles sobre esta nueva sintaxis en MDN (campos públicos, campos y métodos privados).
class Check {
static className = "Check"; // static public class field
#value = 3; // # means private!
get #double() { // private getter
return this.#value * 2; // using a private field
}
}
Por lo tanto, puedes eliminar @babel/plugin-proposal-class-properties y @babel/plugin-proposal-private-methods, ya que ahora están habilitados por defecto en @babel/preset-env.
Webpack admite esta sintaxis de forma nativa desde la v5.36.0.
Para versiones anteriores, una solución alternativa que funciona con configuraciones simples de Webpack es habilitar manualmente el plugin acorn-stage3, instalando acorn-stage3 y agregando estas líneas al principio de tu archivo webpack.config.js:
// Require webpack's acorn dependency
const acorn = require(require.resolve("acorn", {
paths: [require.resolve("webpack")]
}));
// Enable the Stage 3 plugin
acorn.Parser = acorn.Parser.extend(require("acorn-stage3"));
Si esto no funciona para ti, o si usas una herramienta diferente que no admite campos de clase, aún necesitas usar los plugins de Babel para transformarlos.
Si estás usando la opción shippedProposals de @babel/preset-env, ahora también incluye los plugins @babel/plugin-proposal-private-property-in-object (presentado en 7.10) y @babel/plugin-proposal-class-static-block (presentado en 7.12): puedes eliminarlos de tu configuración de forma segura.
class Foo {
#bar = "bar";
test(obj) {
return #bar in obj; // private-property-in-object
}
static #x = 42;
static y;
static { // static block
try {
this.y = doSomethingWith(this.#x);
} catch {
this.y = "unknown";
}
}
}
Mejor interoperabilidad entre ESM y CJS
Al importar un archivo CommonJS desde un módulo ECMAScript, Node.js tiene semánticas diferentes a la mayoría de herramientas en el ecosistema JavaScript.
Supongamos que dependes de la siguiente biblioteca:
export default function two() {
return 2;
}
Y el autor de esta biblioteca no la publica tal cual, sino que la compila a CommonJS:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = two;
function two() {
return 2;
}
Cuando importas esta biblioteca con Babel (o TypeScript, Rollup o herramientas similares) y compilas tu código a CommonJS, se verá así:
import two from "two";
console.log(two());
Un día, decides proporcionar dos versiones de tu código: una compilada a CommonJS y otra usando módulos ECMAScript nativos.
Mientras la versión compilada funciona, la versión ESM lanzará TypeError: two is not a function. Esto ocurre porque en Node.js, la importación por defecto no es exports.default de la dependencia, sino todo el objeto module.exports.
Podrías cambiar tu código a:
import two from "two";
console.log(two.default());
Sin embargo, este nuevo código tiene un problema: ahora no funciona cuando se compila, porque two.default no es una función.
Babel v7.14.0 añade una nueva opción importInterop: "node" en el plugin @babel/plugin-transform-modules-commonjs que permite que las declaraciones import coincidan con el comportamiento nativo de Node.js. Puedes leer más sobre esta opción en la documentación.
Nicolò de nuestro equipo también contribuyó con una opción similar para @rollup/plugin-commonjs, que estará disponible en la próxima versión. Nuestro objetivo es ayudar al ecosistema a migrar a módulos ECMAScript nativos proporcionando una ruta de migración más sencilla.
TypeScript 4.3
La nueva versión de TypeScript, que se lanzará como estable en mayo, incluye varias características nuevas:
-
Modificadores
overrideen elementos de clase -
Firmas de índice estáticas (
[key: KeyType]: ValueType) en clases -
get/seten declaraciones de tipos
Puedes leer más sobre ellas en la publicación de TypeScript 4.3. Esto es compatible a través de @babel/preset-typescript.
Expresiones async do
Las expresiones async do son una propuesta en Etapa 1 construida sobre la propuesta de expresiones do.
Permiten usar bloques asíncronos dentro de código síncrono, y estos bloques se evalúan como una promesa:
function sync() {
let x = async do {
let res = await Promise.resolve("Third!");
console.log("Second!");
res;
};
console.log("First!");
x.then(console.log);
}
console.log(sync());
// Logs:
// - "First!"
// - "Second!"
// - "Third!"
Puedes probar esta propuesta (¡y reportar comentarios!) agregando los plugins @babel/plugin-proposal-do-expressions y @babel/plugin-proposal-async-do-expressions a tu configuración de Babel.
Estas propuestas son altamente experimentales. Pueden, y es probable que sigan evolucionando. Podrían pasar años antes de que se estandaricen, e incluso podrían ser rechazadas por completo. Puedes probarlas, pero no recomendamos usarlas en producción.
¿Tienes algún comentario o pregunta? ¡Comenta en GitHub!