Anunciando Dart 2.6 con dart2native: Compila Dart a ejecutables nativos autocontenidos
Anunciando Dart 2.6, que incluye dart2native para compilar aplicaciones de Dart a ejecutables nativos autocontenidos para Windows, macOS y Linux
Dart ya ofrece un conjunto extenso de compiladores para construir código optimizado para producción para dispositivos móviles y la web. Estos compiladores flexibles permiten a nuestros socios de framework apuntar a una amplia gama de formatos: apps de Flutter en Android e iOS, apps de Flutter en la web y desktop, apps de AngularDart en la web, y Google Assistant en dispositivos embebidos.
Hoy anunciamos dart2native, una extensión de nuestro conjunto de compiladores existente, con la capacidad de compilar programas de Dart a ejecutables autónomos que contienen código máquina compilado ahead-of-time. Con dart2native, puedes crear herramientas para la línea de comandos en
macOS, Windows o Linux usando Dart. La imagen de anuncio de esta característica fue implementada
usando la característica misma :-)
Dart Native y el compilador dart2native
#Dart ha soportado compilación AOT (ahead-of-time) a código máquina nativo durante varios años, y Dart Native es por lo tanto tecnología bastante madura. Sin embargo, en el pasado solo expusimos esta capacidad en dispositivos móviles iOS y Android, vía Flutter.
Con dart2native, estamos extendiendo nuestro soporte de compilación nativa para soportar sistemas operativos de escritorio tradicionales que ejecutan macOS, Windows y Linux. Como los ejecutables creados con
dart2native son autónomos, pueden ejecutarse en máquinas que no tienen el SDK de Dart instalado. Y como están compilados con el compilador AOT de Dart, los ejecutables empiezan a ejecutarse en solo unos milisegundos. Al igual que con otros compiladores y runtimes de Dart, el mismo conjunto de ricas y consistentes
librerías core está disponible en Dart al compilar a código nativo.
Hemos escuchado a muchos clientes pedir compilación AOT para sistemas operativos de escritorio — el sexto issue mejor valorado en nuestro tracker de issues — así que estamos encantados de poder hacer esta característica disponible.
Si usabas dart2aot antes, entonces a partir de 2.6 usarás dart2native. Proporciona un superconjunto de la funcionalidad de dart2aot.
Construyendo apps de línea de comandos con dart2native
#El compilador dart2native es una excelente opción para construir y desplegar apps basadas en Dart para la línea de comandos. Estas apps a menudo usan librerías como
dart:io (I/O básico),
package:[http](https://pub.dev/packages/http) (red) y package:[args](https://pub.dev/packages/args)
(análisis de argumentos). Revisemos los conceptos básicos de compilar una app “hello, world” a un ejecutable:
El código fuente hello.dart:
main() {
print(‘Hello Dart developers’);
}
Compila hello.dart a un ejecutable hello:
$ dart2native src/hello.dart -o hello
Generated: /Users/mit/hello
Ejecuta hello midiendo el tiempo de ejecución:
$ time ./hello
Hello Dart developers
real 0m0.049s
user 0m0.018s
sys 0m0.020s
¡Nota cómo el comando se inicia, imprime a stdout, y termina en un tiempo combinado de solo 49 milisegundos!
Hemos visto a algunos desarrolladores de Dart ya experimentar con dart2native para herramientas de línea de comandos:
-
Natalie del equipo de SASS (una popular herramienta de extensión de CSS) reporta que después de cambiar su implementación de SASS basada en Dart para compilar con dart2native, ahora es competitiva en rendimiento con LibSass, una implementación basada en C++.
-
Filip del equipo de Dart DevRel recompiló su herramienta linkchecker con dart2native, y vio una aceleración de 27x al revisar sitios pequeños.
Interoperabilidad con código C vía dart:ffi
#Las apps nativas a menudo necesitan acceder a funcionalidad nativa del sistema operativo circundante. Estos APIs del sistema típicamente se exponen en librerías nativas basadas en C, y Dart soporta la interoperabilidad con estas librerías vía
dart:ffi, nuestro nuevo mecanismo para C interop, que lanzamos en vista previa en
Dart 2.5. El compilador
dart2native es compatible con dart:ffi, por lo que puedes crear y compilar apps de Dart nativas que lo usen.
Un miembro del equipo recientemente usó dart:ffi para crear una librería dart_console
para desarrollo de apps de consola, que tiene funcionalidad como obtener las dimensiones de la ventana, leer y establecer la posición del cursor, gestionar colores, y leer teclas y secuencias de control. La capacidad de usar
dart:ffi hace de Dart un lenguaje muy poderoso para apps de consola.
kilo: un editor de código de 7MB escrito en menos de 500 líneas de código Dart
#Usando las librerías core de Dart, dart:ffi y la librería dart_console, podemos crear apps de consola bastante interesantes. El paquete dart_console incluye una demo completa de
kilo, un editor de texto de consola escrito en solo ~500 líneas de código Dart. El nombre kilo viene de su origen,
kilo.c, que era una implementación en C de aproximadamente 1000 líneas de código.
Con el nuevo compilador dart2native podemos empaquetar esto fácilmente, y terminamos con un editor de código autónomo de 7MB. Aquí hay una demo de compilar el editor, y luego usar el editor compilado para editar su propio código fuente para corregir un bug:
Construyendo servicios con dart2native
#Otro uso potencial del compilador dart2native es para pequeños servicios — por ejemplo, un backend que soporta una app frontend escrita con Flutter. En los últimos años, una tendencia creciente ha sido el uso de servicios que se ejecutan en serverless computing. Estos son servicios totalmente gestionados que escalan automáticamente, incluyendo escalar hacia arriba y hacia abajo hasta cero (no ejecutándose), proporcionando el potencial de reducir enormemente el costo porque se facturan solo cuando se ejecutan realmente. Google Cloud hace disponible el serverless computing vía Cloud Run.
Para backends serverless es crítico que el servicio se inicie rápidamente. Tradicionalmente, los servicios basados en Dart se han ejecutado con nuestro compilador JIT (just-in-time), pero la ejecución basada en JIT tiene una alta latencia al iniciar ya que el código necesita ser compilado y calentado antes de que pueda empezar a ejecutarse. Al compilar el código de tu servicio ahead-of-time a código nativo, puedes evitar esta latencia y empezar a ejecutar inmediatamente. Además, con código nativo puedes crear servicios de Dart que tienen una pequeña huella en disco y son autónomos, reduciendo enormemente el tamaño del contenedor en el que se ejecuta el servicio de Dart. El desarrollador de Dart Paul Mundt recientemente documentó sus experiencias usando el compilador dart2native; pudo reducir el tamaño de su imagen Docker en un 91% de 220MB usando código compilado con JIT a solo 20MB usando código nativo. Consulta nuestra documentación para más detalles sobre apps del lado del servidor y paquetes.
Disponibilidad
#El compilador dart2native está disponible en el SDK de Dart a partir de la versión 2.6, que está disponible desde hoy en
dart.dev/get-dart. Una vez que hayas instalado el SDK, deberías ver el nuevo compilador dentro del directorio bin/ y en tu
PATH. Dart.dev tiene más documentación.
Si obtienes el SDK de Dart vía Flutter, ten en cuenta que las compilaciones actuales de Flutter tienen soporte incompleto de dart2native. Recomendamos que instales el SDK de Dart 2.6 desde dart.dev/get-dart.
Limitaciones conocidas
#Esta versión inicial del compilador dart2native tiene algunas limitaciones conocidas, listadas abajo. Puedes informarnos qué issues son importantes para ti añadiendo un “thumbs up” al issue en nuestro tracker de issues de GitHub.
-
Sin soporte de compilación cruzada (issue 28617): El compilador dart2native soporta crear código máquina solo para el sistema operativo en el que se está ejecutando. Por lo tanto, necesitarás ejecutar el compilador tres veces — en macOS, Windows y Linux — si quieres crear ejecutables para los tres. Una forma de hacer esto es usando un proveedor de CI (Integración Continua) que soporte los tres sistemas operativos.
-
Sin soporte de firma (issue 39106): Los ejecutables producidos usan un formato que no es compatible con herramientas de firma estándar como
codesignysigntool. -
Sin soporte para
dart:mirrorsydart:developer(consulta librerías core de Dart).
Otros cambios en Dart 2.6
#La versión 2.6 del SDK de Dart también tiene algunos otros cambios.
Lanzamos una vista previa de dart:ffi, nuestro nuevo mecanismo para C interop, en
Dart 2.5. Dart 2.6 tiene una nueva versión de
dart:ffi. Esta nueva versión tiene una serie de cambios disruptivos del API para hacer nuestros APIs más fáciles de usar, proporcionar más seguridad de tipos y proporcionar acceso conveniente a la memoria. Para detalles adicionales, consulta el
changelog de Dart 2.6. Con estos cambios
dart:ffi se gradúa a beta, y esperamos que los cambios del API sean mucho menos frecuentes de ahora en adelante, y se espera una estabilidad general alta. Por favor continúa dándonos comentarios vía el
tracker de issues.
Dart 2.6 también contiene una vista previa de una emocionante nueva característica del lenguaje, métodos de extensión. Aún nos queda un poco de trabajo de pulido y herramientas para completar esta característica, pero esperamos lanzarla formalmente en nuestra próxima versión del SDK de Dart. Tendremos mucho más que decir sobre los métodos de extensión entonces; por ahora puedes leer sobre las consideraciones de diseño detrás de la característica.
Próximos pasos
#Descarga el SDK de Dart 2.6 (dart.dev/get-dart), construye algo genial con dart2native, y luego cuéntanos sobre ello. Si estás dispuesto a compartir los detalles, por favor deja una respuesta al final de este artículo. ¡Estamos emocionados de ver lo que construyes!