Anunciando Dart 2.14

Soporte para Apple Silicon, y productividad mejorada con lints por defecto, mejores herramientas y nuevas características del lenguaje

Hoy lanzamos la versión 2.14 del SDK de Dart, el próximo release en nuestro viaje continuo para hacer la mejor plataforma para construir apps a través de una combinación única de portabilidad, productividad y robustez. Esta vez tenemos mejor soporte para Apple Silicon, y varias mejoras de productividad como lints estándar para detectar errores mientras escribes tu código a través de análisis de estilo de código, una herramienta pub más rápida, mejor formateo de código con cascades, y algunas pequeñas características del lenguaje.

Banner del release de Dart 2.14 destacando Apple Silicon, lints compartidos, mejores herramientas, y actualizaciones del lenguaje.

Soporte de Apple Silicon en el SDK de Dart

#

Desde que Apple anunció sus nuevos procesadores Apple Silicon a finales de 2020, hemos trabajado en actualizar el SDK de Dart para añadir soporte para ejecución nativa en los nuevos procesadores. Los cambios necesarios han estado disponibles en el canal dev por un tiempo, en el canal beta durante el último mes, y a partir de Dart 2.14.1 ahora están disponibles en el canal estable de Dart. Cuando descargues un SDK de macOS, asegúrate de elegir la opción ARM64. Ten en cuenta que el SDK de Dart incluido en el SDK de Flutter aún no tiene estas mejoras.

El soporte incluye tanto la ejecución del SDK/Dart VM mismo en Apple Silicon, como el soporte para compilar ejecutables (con dart compile) que se ejecutan en Apple Silicon. Las herramientas de línea de comandos de Dart se inician mucho más rápido ahora que usan soporte nativo de Apple Silicon.

Lints estándar compartidos para Dart y Flutter

#

Los desarrolladores a menudo prefieren que su código siga un cierto estilo. Muchas de estas reglas no son solo preferencias estilísticas (como la conocida discusión de tabs vs. espacios), sino que cubren estilos de código que probablemente lleven a errores o introduzcan bugs. Como ejemplo, la guía de estilo de Dart requiere usar llaves para todas las estructuras de control de flujo, como las sentencias if-else. Esto previene el clásico problema del dangling else, donde hay ambigüedad sobre cómo interpretar varias sentencias if-else anidadas. Otro ejemplo es la inferencia de tipos. Aunque está bien usar inferencia de tipos al declarar variables con valores iniciales, es importante especificar el tipo al declarar variables no inicializadas, para asegurar la seguridad de tipos.

Una opción para hacer cumplir un buen estilo de código es tener alguna forma de verificación humana, a menudo vía una revisión de código. Sin embargo a menudo es mucho más efectivo hacer cumplir las reglas vía análisis estático que se ejecuta mientras escribes tu código.

En Dart, este análisis estático es altamente configurable, y tenemos cientos de reglas de estilo (también conocidas como lints). Con esta abundancia de opciones, puede ser un poco abrumador elegir qué reglas habilitar. El equipo de Dart mantiene una guía de estilo de Dart, que describe lo que creemos es la mejor forma de escribir y estilizar código Dart, pero históricamente no hemos tenido un conjunto oficial de reglas de linter que correspondan a la guía de estilo.

Muchos desarrolladores — y el motor de scoring del sitio pub.dev — han usado el conjunto de reglas de lint pedantic. Pedantic, sin embargo, tiene sus orígenes en la guía de estilo interna de Google para Dart, que por razones históricas difiere de la guía de estilo general de Dart. Además, el framework de Flutter nunca usó el conjunto de reglas pedantic, y en su lugar tenía su propio conjunto de reglas canónicas.

Esto puede sonar un poco desordenado, y de hecho lo era. Pero con los releases de hoy estamos felices de anunciar que ahora tenemos un nuevo conjunto de colecciones de lints que implementan la guía de estilo, y que los SDKs de Dart y Flutter han sido actualizados para usar estos conjuntos de reglas por defecto para nuevos proyectos. Los conjuntos de reglas son:

  • package:lints/core.yaml: ****Las reglas principales de la guía de estilo de Dart que creemos que todo código Dart debería seguir. El motor de scoring de pub.dev ha sido actualizado para usar estas en lugar de pedantic.

  • package:lints/recommended.yaml: Las reglas core, más reglas recomendadas adicionales. Este conjunto es recomendado para todo código Dart general.

  • package:flutter_lints/flutter.yaml: Las reglas core y recomendadas, más reglas recomendadas adicionales específicas de Flutter. Este conjunto es recomendado para todo código de Flutter.

Si tienes proyectos existentes, recomendamos fuertemente que actualices a estos nuevos conjuntos de reglas. Actualizar desde pedantic toma solo unos pocos pasos.

Formateador de Dart y cascades

#

Hicimos varias optimizaciones a cómo el formateador de Dart formatea código con cascades. Antes, el formateador en algunos casos producía un formateo confuso. Por ejemplo, ¿sobre qué se llama doIt() en este ejemplo?

var result = errorState ? foo : bad..doIt();

Podría parecer que siempre se llama sobre bad, pero en realidad el cascade aplica a toda la expresión ?, así que el cascade se llama sobre el resultado de esa expresión, y no solo sobre la cláusula false. El nuevo formateador deja esto claro:

var result = errorState ? foo : bad
  ..doIt();

Otros cambios se relacionan con cómo se formatean las líneas con múltiples cascades, y cuánto se indentan los cascades en general. También aumentamos enormemente la velocidad de formateo de código que contiene cascades; en código Dart generado para protocol buffers, estamos viendo hasta una mejora de 10x en la velocidad de formateo.

Para todos los detalles, consulta el issue de seguimiento.

Soporte de pub para ignorar archivos

#

Actualmente cuando publicas un paquete al repositorio comunitario de pub.dev, pub toma todos los archivos en esa carpeta con algunas excepciones, saltando los archivos ocultos (los que comienzan con un punto: .) y los archivos listados en .gitignore. Varios desarrolladores han solicitado la capacidad de controlar qué archivos se ignoran fuera de la lista en .gitignore. Por ejemplo, podrías tener algunas herramientas de desarrollo internas en una carpeta tool/ que usas para mantener tu paquete, pero que no son relevantes para las personas que usan tu paquete.

El comando pub actualizado en Dart 2.14 soporta un nuevo archivo .pubignore, donde puedes listar los archivos que no quieres subir a pub.dev. Este archivo usa el mismo formato que los archivos .gitignore. Para más detalles, consulta la documentación de publicación de paquetes.

Rendimiento de pub y dart test

#

Aunque pub es quizás más usado para gestionar dependencias de código, también tiene una segunda utilidad importante: potenciar herramientas. Un ejemplo de esto es la herramienta de test de Dart, expuesta vía el comando dart test. Este comando es realmente solo un wrapper alrededor del comando pub run test:test, que ejecuta el entrypoint de test en package:test. Antes de invocar ese entrypoint, pub primero lo compila a código nativo que puede ejecutarse más rápido.

Antes de Dart 2.14, cualquier cambio en el pubspec (incluyendo los no relacionados con package:test) invalidaría este build de test, y verías un montón de output como este conteniendo “Precompiling executable”:

$ dart test
Precompiling executable... (11.6s)
Precompiled test:test.
00:01 +1: All tests passed!

En Dart 2.14, pub es mucho más inteligente sobre cuándo invalidar el build step, así que el build solo ocurre cuando la versión cambia. Además, mejoramos cómo realizamos ese build step usando paralelización, así que el step mismo se completa mucho más rápido. Hemos visto que toma la mitad del tiempo en algunos paquetes que hemos testeado.

Nuevas características del lenguaje

#

Dart 2.14 también contiene varias características pequeñas del lenguaje. Esta vez nos enfocamos en mejoras más específicas que quizás son de utilidad más reducida, pero habilitan casos de uso más especializados que no estaban soportados previamente.

Primero, añadimos un nuevo operador de triple shift (>>>). Esto es similar al operador de shift existente (>>), pero donde >> realiza un desplazamiento aritmético, >>> realiza un desplazamiento lógico, o sin signo, donde los bits de cero se desplazan hacia el bit más significativo independientemente de si el número que se desplaza es positivo o negativo.

También hemos removido una antigua restricción en los argumentos de tipo, que no permitía usar tipos de funciones genéricas como argumento de tipo. Todos los siguientes eran inválidos antes de 2.14, pero ahora están permitidos:

late List<T Function<T>(T)> idFunctions;
var callback = [<T>(T value) => value];
late S Function<S extends T Function<T>(T)>(S) f;

Y finalmente, hemos hecho un pequeño ajuste a los tipos de anotaciones. (Anotaciones como @Deprecated se usan comúnmente en código Dart para capturar metadatos.) Previamente las anotaciones no podían recibir argumentos de tipo, así que código como @TypeHelper<int>(42, "The meaning") no estaba permitido. Esta restricción ha sido removida ahora.

Cambios en paquetes y librerías core

#

Hemos hecho varias mejoras a los paquetes y librerías core de Dart, incluyendo:

  • dart:core: Añadidos los métodos estáticos hash, hashAll y hashAllUnordered a la clase Object. Estos pueden usarse para combinar los hash codes de múltiples objetos de forma consistente (ejemplo de hashAll).

  • dart:core: La clase nativa DateTime ahora maneja mejor la hora local alrededor de los cambios de horario de verano que no son exactamente de una hora — por ejemplo Lord Howe Island, Australia, que usa un cambio de 30 minutos.

  • package:ffi: Añadido soporte para gestionar memoria usando un allocator de arena (ejemplo). Las arenas son una forma de gestión de memoria basada en regiones, donde los recursos se liberan automáticamente una vez que se sale de la arena/región.

  • package:ffigen: Ahora soporta generar typedefs de Dart a partir de typedefs de C.

Breaking changes

#

Dart 2.14 también contiene varios breaking changes previamente anunciados más pequeños. Se espera que estos cambios afecten solo a unos pocos casos de uso especializados.

#46545: Remoción del soporte para ECMAScript5

#

Todos los navegadores modernos soportan versiones recientes de ECMAScript, así que hace dos años anunciamos un plan para deprecar el soporte para ECMAScript 5 (ES5). Esto nos permite aprovechar mejoras en el último ECMAScript y generar un output más pequeño. En Dart 2.14 este trabajo está completo, y los compiladores web de Dart ya no soportan ES5. Como resultado, los navegadores antiguos — como IE11 — ya no están soportados.

#46100: Deprecación de stagehand, dartfmt y dart2native

#

En el blog post de Dart 2.10 de octubre de 2020, anunciamos nuestro trabajo para combinar todas las herramientas de desarrollo CLI de Dart en una sola herramienta dart combinada (similar a la herramienta flutter). Como parte de esa evolución, Dart 2.14 deprecó los antiguos comandos dartfmt y dart2native, y discontinuó stagehand. Todas estas herramientas tienen reemplazos equivalentes en la herramienta dart unificada.

#45451: Deprecación de VM Native Extensions

#

Hemos deprecado las Native Extensions del Dart VM, nuestro mecanismo anterior para llamar código nativo desde código Dart. Dart FFI (foreign function interface) es nuestro mecanismo actual para este caso de uso, y estamos evolucionándolo activamente para que sea aún más potente y fácil de usar.

Actualización de null safety

#

Lanzamos sound null safety en marzo en el release de Dart 2.12. Null safety es la última gran característica de productividad de Dart, diseñada para ayudarte a evitar errores de null — una clase de bugs que a menudo son difíciles de detectar.

Desde nuestra última actualización, hemos visto un gran progreso en las migraciones de paquetes y apps existentes para habilitar los beneficios de verificación sound de null safety. Para los paquetes en pub.dev, el 100% de los top-250 paquetes ahora soportan null safety, y el 94% de los top-1000 lo soportan. Esto significa que más desarrolladores pueden ejecutar sus apps con sound null safety completa. Los análisis muestran que el 56% de las sesiones de flutter run se ejecutan con soundness completa. ¡Gracias a todos los desarrolladores del ecosistema por su trabajo de migración!

Disponibilidad de 2.14 e impulso continuo

#

El SDK de Dart mejorado que contiene los cambios anteriores está disponible hoy en los SDKs de Dart 2.14.1 y Flutter 2.5. Esperamos que disfrutes las nuevas mejoras y características.

También, queremos aprovechar la oportunidad para extender nuestro agradecimiento a la increíble comunidad de Dart. Como se evidencia a través de varias actualizaciones recientes a encuestas de lenguajes de programación, el impulso de Dart es fuerte. El bien respetado ranking de RedMonk menciona “el remarkable ascenso de Dart” y coloca a Dart en el top 20 por primera vez. La comprehensiva Encuesta de Desarrolladores 2021 de StackOverflow fue igualmente deliciosa de leer: Dart fue reportado como el 7º lenguaje de programación más amado por los desarrolladores. Estamos verdaderamente encantados de ver que la plataforma Dart tenga un crecimiento e impulso continuos.

Más de Dart