Saltar al contenido principal

7.8.0 Publicado: ECMAScript 2020, archivos de configuración .mjs y mejoras en @babel/cli

· 9 min de lectura
Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

¡Esta es la primera publicación del año! 🎉

Babel 7.8.0 soporta las nuevas características de ECMAScript 2020 por defecto: ya no necesitas habilitar plugins individuales para fusión nula (??), encadenamiento opcional (?.) e import() dinámico con preset-env.

También terminamos de alinear nuestros distintos archivos de configuración con los formatos soportados nativamente por Node.js, un proceso que iniciamos en el lanzamiento 7.7.0.

Finalmente, la CLI de Babel ahora soporta dos nuevas opciones: --out-file-extension y --copy-ignored.

Puedes leer el registro de cambios completo en GitHub.


¡Un reconocimiento especial a Abdul Ali, Jack Isherwood, Jayen Ashar, James Beavers, Klaus Meinhardt, Oleksandr Fediashov, Siddhant N Trivedi, Tsubasa Nakayama, Yordis Prieto y ZYSzys por sus primeros PRs!

También queremos agradecer a Thomas Smith por ofrecerse como voluntario para ayudarnos a mantener el importante plugin de resaltado de sintaxis babel-sublime, y dar la bienvenida a Raja Sekar, ¡nuestra incorporación más reciente a la organización de Babel!

Si tú o tu empresa desean apoyar a Babel y la evolución de JavaScript, pero no saben cómo, pueden donar en nuestro Open Collective y, mejor aún, ¡trabajar directamente con nosotros en la implementación de nuevas propuestas de ECMAScript! Al ser un 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 detalles.

Recientemente publicamos una entrada sobre financiamiento detallando nuestros planes y objetivos. ¡Échale un vistazo!

Soporte por defecto para ECMAScript 2020 (#10811, #10817, #10819, #10843)

¡Durante la última reunión, TC39 promovió a Etapa 4 las propuestas de fusión nula y encadenamiento opcional!

El operador de fusión nula te permite proporcionar un valor alternativo cuando una expresión se evalúa como null o undefined:

JavaScript
const name = person.fullName ?? "Anonymous";
console.log(`Hello, ${name}!`);

Esto es similar al funcionamiento del operador OR lógico (||). La diferencia radica en que mientras || verifica valores "falsy" (como undefined, null, false, 0, 0n y ""), ?? solo verifica valores "nullish". Esto se alinea mejor con el modelo mental de "valor no proporcionado" y funciona más eficazmente con valores que podrían ser "falsy" pero válidos:

JavaScript
const element = { index: 0, value: "foo" };

const index = element.index ?? -1; // 0 :D
const index = element.index || -1; // -1 :(

La propuesta de encadenamiento opcional utiliza este mismo concepto de "valores nullish", permitiendo accesos opcionales a propiedades en valores que podrían ser nulos. También admite llamadas a funciones opcionales y propiedades computadas.

JavaScript
const city = person.address?.city; // person.address could be not defined
const isNeighbor = person.address?.isCloseTo(me);

person.sayHayUsing?.("Twitter"); // The person.sayHayUsing method could be not defined

¡Ahora puedes usar estas nuevas funciones con seguridad en tu código! Si ya utilizas @babel/preset-env, puedes emplear estos operadores y se compilarán según tus objetivos, igual que cualquier otra función de ECMAScript. Si estabas usando directamente @babel/plugin-proposal-nullish-coalescing-operator o @babel/plugin-proposal-optional-chaining, puedes eliminarlos de tu configuración:

{
"presets": [
["@babel/env", { "targets": ["last 2 versions"] }]
],
"plugins": [
- "@babel/proposal-optional-chaining",
- "@babel/proposal-nullish-coalescing-operator"
]
}

Estas funciones ahora también están habilitadas por defecto en @babel/parser: si lo usabas directamente, puedes eliminar los plugins de análisis nullishCoalescingOperator y optionalChaining. También habilitamos el análisis para import() dinámico (incluido en @babel/preset-env desde la v7.5.0), por lo que puedes eliminar con seguridad el plugin dynamicImport.

Soporte para todas las extensiones de archivo de configuración (#10783 y #10903)

Babel 6 admitía un único archivo de configuración basado en JSON: .babelrc.

En Babel 7.0.0, introdujimos babel.config.js (con lógica de resolución diferente) y .babelrc.js. Los archivos de configuración JavaScript son útiles para escenarios que requieren mayor flexibilidad. Esta era la situación:

Node.js file typebabel.config.__.babelrc.__
.js✔️ Supported✔️ Supported
.json❌ Not supported❔ Supported, with implicit extension
consejo

¡Recomendamos encarecidamente leer sobre las diferencias entre babel.config.js y .babelrc.js!

Recientemente, Node.js 13.2.0 añadió soporte para módulos ECMAScript nativos y las extensiones .cjs y .mjs. En Babel 7.7.0 agregamos soporte para archivos de configuración .cjs, permitiendo a los usuarios habilitar "type": "module" en su package.json sin romper Babel, junto con soporte para babel.config.json que permite configuración estática para todo el proyecto.

Node.js file typebabel.config.__.babelrc.__
.js✔️ Supported when "type": "module" is not enabled✔️ Supported when "type": "module" is not enabled
.json✔️ Supported❔ Supported, with implicit extension
.cjs✔️ Supported✔️ Supported
.mjs❌ Not supported❌ Not supported

Esta versión alinea Babel con los tipos de archivo soportados nativamente por Node.js, permitiendo .babelrc.json, babel.config.mjs y .babelrc.mjs.

Node.js file typebabel.config.__.babelrc.__
.js✔️ Supported✔️ Supported
.json✔️ Supported✔️ Supported
.cjs✔️ Supported✔️ Supported
.mjs✔️ Supported✔️ Supported

Recuerda que los módulos ECMAScript son asíncronos: por eso, por ejemplo, no puedes usar require() con ellos y debes usar import(), que devuelve una promesa.

Por estas razones, solo pueden usarse al invocar Babel mediante puntos de entrada basados en promesas o callbacks. Ya funcionan con @babel/cli, babel-loader y gulp-babel, y funcionarán con la próxima versión de rollup-plugin-babel. Ten en cuenta que aún no son compatibles con babel-eslint.

Nuevas opciones de CLI (#9144 y #10887)

Añadimos dos nuevas opciones a @babel/cli: --copy-ignored y --out-file-extension.

--copy-ignored se utiliza para copiar archivos no transpilados por Babel, ya sea porque se ignoran mediante la opción CLI --ignore o porque "ignore" está configurado en un archivo de configuración.

precaución

Para mantener la compatibilidad con versiones anteriores, en Babel 7.8.4 el valor predeterminado de la opción --copy-ignored se ha cambiado a true. Si deseas desactivarlo, puedes usar --no-copy-ignored.

Esto funciona de manera similar a la opción --copy-files, pero --copy-files está diseñada para copiar cualquier archivo que no sea transpilado porque no es JavaScript (por ejemplo, .css o .json), en lugar de archivos explícitamente ignorados.

--out-file-extension permite configurar la extensión de los archivos generados por Babel. Por ejemplo, si estás transpilando archivos .js que contienen módulos ECMAScript nativos en Node.js y quieres generar archivos CommonJS, podrías necesitar usar la extensión .cjs:

Shell
$ babel src --out-dir lib-cjs --out-file-extension cjs

Preparando para Babel 8

Estamos comenzando a trabajar en el lanzamiento de Babel 8.0.0 en nuestro issue general: #10746.

Babel 8 solo contendrá cambios importantes: lanzaremos una versión menor el mismo día, que incluirá todas las correcciones de errores y nuevas funcionalidades que de otro modo se habrían incluido en 8.0.0.

Aunque no anticipamos una migración compleja, hay dos aspectos que queremos destacar:

Extraer el parser de objetivos y datos de compatibilidad de preset-env (#10899)

Actualmente, varios presets de terceros utilizan la lógica interna de @babel/preset-env para analizar objetivos de compilación o recuperar información sobre plugins y polyfills necesarios.

Hemos decidido soportar oficialmente estos dos casos de uso mediante dos nuevos paquetes públicos:

  • @babel/helper-compilation-targets, que exporta una función para normalizar los objetivos especificados y algunas utilidades relacionadas:

    JavaScript
    import getTargets from "@babel/helper-compilation-targets";

    getTargets({
    browsers: ["last 2 chrome versions"],
    node: 10,
    }) ==
    {
    chrome: "77.0.0",
    node: "10.0.0",
    };
  • @babel/compat-data, que contiene una colección de archivos JSON donde almacenamos todas las versiones de navegadores que requieren cada plugin o polyfill de core-js@2. Se genera principalmente desde compat-table, aunque podríamos agregar otras fuentes en el futuro.
    Si necesitas datos para polyfills de core-js@3, puedes usar core-js-compat.

Planeamos deshabilitar el uso de archivos internos a partir de Babel 8. Si dependes de otras API internas, ¡por favor infórmanos!

Introducción de validación de AST más estricta (opcional) (#10917)

@babel/types ya realiza muchas verificaciones para garantizar que el AST que construyes sea válido. Por ejemplo, este código fallará porque no puedes usar una declaración donde se espera una expresión:

JavaScript
// foo = if (true) {}

t.assignmentExpression(
"=",
t.identifier("foo"),
t.ifStatement(t.booleanLiteral(true), t.blockStatement([]))
);

Estamos introduciendo validaciones más estrictas para evitar ASTs aún más inválidos: no solo desde la perspectiva de la estructura del árbol, sino también asegurando que los nodos en la posición correcta contengan información válida. Por ejemplo, a partir de Babel 8 t.identifier("123") será inválido porque 123 no es un identificador válido.

No podemos habilitar estas verificaciones en Babel 7.8.0 porque el riesgo de romper plugins existentes es demasiado alto, pero te recomendamos encarecidamente que actives estas verificaciones estrictas usando la variable de entorno BABEL_TYPES_8_BREAKING=true y reportes incidencias (¡o mejor, envía PRs!) para corregir los plugins que uses y que no funcionen con Babel 8.