Anunciando Dart 3.7

Es un nuevo año, y momento para un nuevo lanzamiento estable de Dart. ¡Bienvenido a Dart 3.7!

El tema de este release es productividad del desarrollador. Hemos hecho el lenguaje Dart más consistente ajustando cómo maneja las wildcard variables. También hay un estilo totalmente nuevo en el formateador de Dart, nuevos quick fixes y lints en el analyzer, y varias características geniales nuevas en pub.dev. ¡Vamos a los detalles!

Banner del release de Dart 3.7 con el logo de Dart y un ícono de diana animado.
Anunciando Dart 3.7

Actualización de macros

#

Recientemente publicamos actualizaciones en el issue tracker, así como un post en el blog, declarando que estamos deteniendo el trabajo en nuestra característica experimental de macros. Nos gustaría agradecer a la comunidad por su comprensión de este desafortunado resultado.

Con este cambio, sin embargo, el equipo recupera algo de capacidad para invertir en otros desarrollos valiosos. Ya estamos explorando mejoras al rendimiento de build_runner, aún esperamos lanzar la característica de lenguaje augmentations (quizás en una forma ligeramente diferente), y esperamos encontrar formas nuevas y más directas de soportar el modelado de datos y el manejo de serialización y deserialización (desde y hacia JSON, por ejemplo).

Característica de lenguaje Wildcard variables

#

Las variables locales y parámetros nombrados _ son ahora lo que los lenguajes funcionales llaman "wildcards". Esto significa que el nombre es un placeholder y no declara ninguna variable actual.

Actualmente en Dart, es común usar _ como nombre de un parámetro de callback si el cuerpo del callback no necesita realmente usar el argumento, así:

dart
void announceCompletion(Future<void> future) {
  future.then((_) { // <--
    print('Complete!');
  });
}

Pero, si un callback tiene múltiples parámetros que no necesitas usar, terminas nombrándolos _, __, ___, etc., porque de lo contrario los nombres colisionan. Ahora, en Dart 3.7, los parámetros y variables locales nombrados _ en realidad no crean una variable, así que no hay posibilidad de colisión de nombres. Puedes usar _ para múltiples parámetros, como en:

dart
void announceFailure(Future<void> future) {
  future.onError((_, _) { // <--
    print('Error!');
  });
}

Si tienes código que declara un parámetro o variable nombrado _ y lo usa, ese código ya no funcionará en Dart 3.7. Por ejemplo:

dart
var [1, 2, 3].map((_) {
  return _.toString();
  //     ^ Error! Reference to unknown variable.
});

Tendrás que renombrar el parámetro o variable local en esta situación. Este cambio del lenguaje solo aplica a parámetros y variables locales (no a variables top-level o miembros), así que puedes hacer este renombrado sin romper el API público de tu librería.

Las wildcard variables son una pequeña característica que hace el lenguaje más consistente. Las variables nombradas _ en patterns siempre se han comportado así:

dart
var [_, _, third, _, _] = [1, 2, 3, 4, 5];
print(third); // Prints "3".

Ahora los parámetros y las variables locales se comportan de la misma manera.

Nuevo estilo de formateo en el formateador de Dart

#

Dart 3.7 incluye un formateador de Dart reescrito (dart format) con un nuevo estilo de formateo. El nuevo estilo se parece al estilo que obtienes cuando añades trailing commas a las listas de argumentos, excepto que ahora el formateador añadirá y eliminará esas comas por ti. Por ejemplo:

dart
// Old style:
void writeArgumentList(
    Token leftBracket, List<AstNode> elements, Token rightBracket) {
  writeList(
      leftBracket: leftBracket,
      elements,
      rightBracket: rightBracket,
      allowBlockArgument: true);
}

// New style:
void writeArgumentList(
  Token leftBracket,
  List<AstNode> elements,
  Token rightBracket,
) {
  writeList(
    leftBracket: leftBracket,
    elements,
    rightBracket: rightBracket,
    allowBlockArgument: true,
  );
}

Este es un gran cambio tanto para la herramienta, la salida que produce, y cómo se comporta. Para hacer la transición lo más suave posible, el estilo de formateo que obtienes depende de la versión del lenguaje del código que estás formateando. Si la versión del lenguaje es 3.6 o anterior, el código se formatea con el estilo antiguo. Si es 3.7 o posterior, obtiene el nuevo estilo.

Cuando actualizas tu paquete para usar Dart 3.7 actualizando la restricción del SDK en el pubspec de tu paquete (¡y ejecutando dart pub get!), estás optando por el nuevo estilo de formateo.

Para determinar la versión del lenguaje de cada archivo que formatea, dart format busca un package_config.json. Esto significa que necesitas ejecutar dart pub get antes de formatear código en tu paquete. Si tienes verificaciones de formato en tu servidor de integración continua, asegúrate de que también ejecute dart pub get.

No pretendemos soportar ambos estilos indefinidamente. En algún momento en el futuro, cuando la mayor parte del ecosistema esté en 3.7 o posterior, el soporte para el estilo antiguo será eliminado.

El nuevo estilo incluye algunas características muy solicitadas:

  • Configuración de ancho de página a nivel de proyecto. Ahora puedes configurar tu ancho de página de formateo preferido a nivel de proyecto en tu archivo analysis_options.yaml, así:
yaml
    formatter:
      page_width: 123
  • Excluir una región de código del formateo. Puedes usar un par de comentarios marcadores especiales para excluir una región de código del formateo automático:
dart
    main() {
      // dart format off
      no   +   formatting     +     here;
      // dart format on
    }

También hay un breaking change. El formateador ya no soporta dart format --fix. En su lugar, usa dart fix para aplicar todos los fixes que dart format podía, y más.

Puedes encontrar más detalles en el CHANGELOG y FAQ.

Quick fixes actualizados y nuevos lints en el analyzer de Dart

#

Siempre estamos mejorando activamente Dart para potenciar la productividad del desarrollador, y eso significa mejorar el analyzer con nuevos lints, quick fixes, y assists en Dart 3.7. Una adición notable es el lint unnecessary_underscores, que soporta la nueva característica de wildcard variables.

Entre la amplia gama de nuevos quick fixes y assists que Dart 3.7 incluye, hay fixes para problemas comunes como palabras clave await faltantes, prefijos de import incorrectos, y violaciones de reglas de lint como cascade_invocations. También hay assists útiles para refactorizar código, como convertir bloques else a else if y envolver widgets de Flutter con Expanded o Flexible.

Puedes encontrar más detalles sobre todos estos, y mucho más, en la lista completa de cambios del analyzer.

Avanzando en la plataforma web de Dart

#

Hace un año, introdujimos nuevas librerías y paquetes para interoperar con JavaScript y APIs del navegador desde Dart. En adelante, la librería principal de JavaScript es dart:js_interop. Para las APIs del navegador, usa package:web.

Como parte de nuestro esfuerzo continuo para migrar el ecosistema de Dart y Flutter a APIs compatibles con WebAssembly, estamos deprecando las APIs legacy asociadas en el SDK de Dart. Siete librerías del SDK de Dart son deprecadas en el release de Dart 3.7:

  • dart:html

  • dart:indexed_db

  • dart:js

  • dart:js_util

  • dart:web_audio

  • dart:web_gl

Planeamos eliminar estas librerías a finales de 2025. Puedes aprender sobre sus reemplazos en la página de interoperabilidad con JavaScript.

Nuevas características de productividad en el sitio de paquetes pub.dev

#

En diciembre lanzamos download counts para paquetes en pub.dev. Estos muestran descargas mensuales junto con un pequeño gráfico que muestra las descargas semanales a lo largo del tiempo.

Hoy, extendemos eso con soporte para ver los download counts por versión del paquete. Ahora es posible tener una indicación de cuántos consumidores de un paquete han actualizado a la última versión (o solo a la última versión major). Estos insights están pensados para ayudar a los autores de paquetes a evaluar el valor de back-portear fixes a versiones major anteriores de un paquete.

Gráfico mostrando descargas semanales para una versión específica de paquete.
Gráfico de descargas semanales, con versiones separadas
Otro gráfico mostrando descargas semanales pero apiladas por versión.
Gráfico de descargas semanales, con versiones apiladas

Dark mode for pub.dev

El modo oscuro para pub.dev ha sido durante mucho tiempo una solicitud popular, y a partir de hoy ya es posible cambiar pub.dev al modo oscuro. Este toggle afecta tanto a las páginas de paquetes como a la documentación del API de paquetes alojada en pub.dev.

Captura de pantalla mostrando el toggle de modo oscuro y la UI en pub.dev.
Modo oscuro para pub.dev

Topics for pub.dev

El año pasado, lanzamos soporte para topics en pub.dev. Puedes añadir topics a tu pubspec.yaml, y si ves topics relacionados que deberían fusionarse puedes proponer su canonicalización con un pull request.

Los usuarios que navegan pub.dev pueden hacer clic en los topics para explorar paquetes relacionados. Anteriormente introdujimos la capacidad de buscar topics en pub.dev, usando palabras clave de búsqueda (como "topic:widget"), pero encontrar estas palabras clave no siempre ha sido fácil. Así que, hemos lanzado un autocompletador tipo IDE para palabras clave de búsqueda en pub.dev. Puedes activarlo presionando ctrl+space, o se activa automáticamente cuando escribes un prefijo coincidente como "topic:" o "license:".

Captura de pantalla mostrando el autocompletador tipo IDE para palabras clave de búsqueda en pub.dev.
Palabras clave de búsqueda de topics

Conclusión

#

Eso es todo por hoy para Dart 3.7. Como siempre, ¡cuéntanos qué piensas! Y no olvides revisar el post del blog del release de Flutter 3.29 de hoy también. ¡Hasta la próxima!

Más de Dart