Anunciando Dart 3.2

Lenguaje y experiencia de desarrollador mejorados, y una actualización sobre aplicaciones web y Wasm

Por: Kevin Moore & Michael Thomsen

Hoy anunciamos Dart 3.2, con una nueva característica del lenguaje para la promoción non-null de private final fields, experiencia de desarrollador mejorada con nuevas capacidades de interop, soporte para extensiones en DevTools, y una actualización de nuestra hoja de ruta web incluyendo soporte para Wasm (también conocido como WebAssembly).

Banner del release de Dart 3.2 destacando actualizaciones del lenguaje, experiencia del desarrollador, y la hoja de ruta web.

Promoción non-null para private final fields

#

Han pasado unos años desde que introdujimos sound null safety en Dart 2.12. Con null safety, puedes declarar qué tipos son nullable (pueden contener un valor, o null) y cuáles son non-nullable (siempre contienen un valor). Null safety combinado con flow analysis detecta cuándo las variables nullable pueden ser "promocionadas" a sus tipos más seguros, non-null:

dart
int definitelyInt(int? aNullableInt) {
  if (aNullableInt == null) {
    return 0;
  }
  // If flow analysis reaches this point,
  // aNullableInt can safely promote to a non-null int.
  return aNullableInt;
}

La promoción de tipos ha sido parte fundamental de null safety desde Dart 2.12, pero estaba limitada a variables locales. Los fields o variables top-level no podían ser promocionados, como en un caso como este:

dart
class Container {
  final int? _fillLevel;
  Container(this._fillLevel);
  check() {
    if (_fillLevel != null) {
      int i = _fillLevel; // Prior to Dart 3.2, causes an error.
    }
  }
}

Esta limitación se debía a varios casos complejos donde el flow analysis no podía determinar de forma segura cuándo o cómo un field podría cambiar. En el caso de la promoción de fields en una clase, por ejemplo, podía ser un problema si una subclase sobrescribe un field con un getter, que a veces devuelve null.

En Dart 3.2, hemos mejorado nuestro motor de flow analysis y ahora podemos hacer type promotion de private final fields. Ahora, el fragmento de código anterior pasa sin errores. Esto aprovecha la idea de que para un private & final field, el valor nunca cambia después de la asignación inicial, por lo que verificarlo una sola vez se considera seguro. La promoción de private final fields está disponible a partir de Dart 3.2, y se aplicará a proyectos que tengan un lower bound del SDK de Dart de 3.2 o superior.

Nuevas opciones de análisis de código en package:lints 3.0

#

Hablando de análisis de código, también hemos hecho una serie de mejoras a nuestras reglas estándar de análisis de código en package:lints. Este paquete contiene el conjunto predeterminado y recomendado de reglas de análisis estático que viene con cualquier nuevo proyecto creado con dart create o flutter create (a través de package:flutter_lints — una extensión de package:lints).

Una nueva versión principal de este conjunto de lints, la versión 3.0, ya está disponible. Esta revisión añadió seis lints al conjunto principal y dos lints al conjunto recomendado. Incluye lints para validar URLs de pubspec, validar que los métodos de colección se invoquen con los argumentos correctos, y más. Para la lista completa de cambios, consulta el changelog. La versión 3.0 será la predeterminada para nuevos proyectos en el próximo release. Para proyectos existentes, puedes actualizar ahora.

Actualización de interoperabilidad de Dart

#

El soporte multiplataforma en una amplia gama de plataformas siempre ha sido un principio fundamental de Dart. Pero aunque una línea de código Dart puede ejecutarse sin cambios en todas esas plataformas, las apps grandes todavía suelen tener la necesidad de interoperar con código existente. Esto puede significar código de proyectos antiguos, o APIs disponibles en otras librerías o APIs del sistema. Hemos hecho una serie de inversiones en esta área, comenzando con FFI para interop con APIs nativas de C. Actualmente estamos trabajando en expandir esto para soportar interop con Java y Kotlin y Objective C y Swift. Para noticias emocionantes sobre JS interop, consulta la sección de Dart web más abajo.

A partir de Dart 3.2, hemos hecho varias mejoras al interop nativo:

  • Hemos introducido el constructor NativeCallable.isolateLocal para C FFI, que crea un puntero de función C a partir de una función Dart arbitraria. Esto es una extensión de la funcionalidad proporcionada por Pointer.fromFunction, que solo puede crear punteros de función a partir de funciones top-level.

  • Hemos actualizado el generador de bindings de Objective-C para usar NativeCallable.listener, que añadimos en Dart 3.1. El generador ahora puede manejar automáticamente APIs que contienen callbacks asíncronos, como Core Motion, por ejemplo. Estas APIs anteriormente requerían escribir parte del código de bindings a mano.

  • Hemos seguido mejorando package:jnigen para interop con Java y Kotlin. Esto nos permitió migrar package:cronet_http — un wrapper del cliente HTTP Cronet de Android — de código de bindings escrito a mano a un wrapper generado automáticamente.

  • Hemos hecho progresos significativos en la característica de Native Assets , que tiene como objetivo resolver varios problemas asociados con la distribución de paquetes Dart que dependen de código nativo. Lo hace proporcionando hooks uniformes para integrarse con varios sistemas de build involucrados en la compilación de aplicaciones Flutter y standalone de Dart. Para una vista previa, consulta la documentación.

Extensiones de DevTools para paquetes Dart

#

Dart DevTools es un conjunto de herramientas de depuración y rendimiento que soporta tanto apps pure-Dart como de Flutter. En Dart 3.2 & Flutter 3.16 anunciamos un nuevo extensions framework que permite a los autores de paquetes crear herramientas personalizadas para su paquete, disponibles directamente en DevTools. Esto permite que los paquetes de pub.dev que contienen frameworks ofrezcan herramientas personalizadas específicas para sus casos de uso. Por ejemplo, los autores de Serverpod han estado trabajando duro en herramientas de desarrollo para su paquete y están emocionados de lanzar una extensión de DevTools en su próximo release 1.2.

Una extensión de DevTools planificada para el próximo release de ServerPod 1.2.
Una extensión de DevTools planificada para el próximo release de ServerPod 1.2

Actualización de Dart web y Wasm

#

Wasm (también conocido como WebAssembly) es un nuevo formato de instrucciones emocionante para navegadores web, que proporciona un formato de código binario portable y neutral respecto a la plataforma para su ejecución en navegadores modernos. Los lenguajes gestionados de alto nivel como Dart usan garbage collection, que se está añadiendo al estándar Wasm. A partir de Chrome 119, el soporte de garbage collection para Wasm (conocido como Wasm-GC) está habilitado por defecto. El soporte de Wasm-GC también llegará en Firefox 120, su próximo release estable. ¿Cuál es el estado con Dart, Flutter, y Wasm-GC?

El compilador de Dart a Wasm está casi completo en funcionalidades. El equipo está muy contento con el rendimiento y la compatibilidad. Nuestro enfoque ahora está en los casos extremos para asegurar que nuestra salida sea rápida en una amplia gama de escenarios.

Para Flutter web, hemos completado un nuevo motor de renderizado "Skwasm". Para maximizar el rendimiento, Skwasm conecta el código compilado de la aplicación directamente a un módulo CanvasKit Wasm personalizado con un binding wasm-to-wasm. También es la primera iteración de soporte de renderizado multi-hilo para Flutter web, lo que mejora aún más los tiempos de frame.

Aún quedan algunas cosas antes de que Flutter web con Wasm esté listo para salir de su estado experimental actual:

  • Compilación dual: Generar tanto salidas Wasm como JavaScript y habilitar la detección de características en tiempo de ejecución para soportar navegadores con y sin soporte Wasm-GC.

  • Interoperabilidad moderna con JavaScript: Un nuevo mecanismo de JS interop basado en extension types para permitir llamadas concisas y con seguridad de tipos entre código Dart, APIs del navegador, y librerías JS, cuando el objetivo es JavaScript y Wasm.

  • APIs del navegador con soporte Wasm: Un nuevo package:web, que reemplaza dart:html (y librerías relacionadas), basado en el mecanismo moderno de JS interop. Esto proporcionará acceso fácil a las APIs del navegador con soporte tanto en objetivos JS como Wasm.

Estamos empezando a migrar varios proyectos internos a package:web y al nuevo mecanismo de JS interop, y esperamos tener más novedades en el próximo release estable. Mientras tanto, puedes obtener los últimos detalles en nuestra página de Soporte para WebAssembly.

Cierre

#

Eso es todo por hoy. Dart 3.2 está disponible ahora en dart.dev, o como parte del release de Flutter 3.16 de hoy. Hasta la próxima, ¡diviértete con Dart!

Más de Dart