Dart вече предлага „обширен набор от компилатори“ за изграждане на оптимизиран за производство код за мобилни устройства и мрежата. Тези гъвкави компилатори позволяват на партньорите ни да се насочат към широк набор от форм-фактори: приложения Flutter на Android & iOS, приложения Flutter на уеб и десктоп, приложения на AngularDart в уеб и Google Assistant на вградени устройства.

Днес обявяваме dart2native, разширение на нашия съществуващ набор от компилатори, с възможност за компилиране на Dart програми в самостоятелни изпълними файлове, съдържащи предварително компилиран машинен код. С dart2native можете да създавате инструменти за командния ред на macOS, Windows или Linux с помощта на Dart. Картината за обявяване на тази функция „е внедрена“ с помощта на самата функция :-)

Dart Native и компилаторът dart2native

Dart поддържа AOT (предварителна) компилация към собствен машинен код от няколко години и следователно „Dart Native“ е доста зряла технология. В миналото обаче разкривахме тази възможност само на мобилни устройства с iOS и Android чрез Flutter.

С dart2native ние разширяваме нашата собствена поддръжка за компилация, за да поддържаме традиционни настолни операционни системи, работещи с macOS, Windows и Linux. Тъй като изпълнимите файлове, създадени с dart2native, са самостоятелни, те могат да работят на машини, които нямат инсталиран Dart SDK. И тъй като са компилирани с AOT компилатора на Dart, изпълнимите файлове започват да се изпълняват само за няколко милисекунди. Както при други компилатори и времена за изпълнение на Dart, същият набор от богати и последователни основни библиотеки е наличен в Dart при компилиране към естествен код.

Чухме, че много клиенти искат компилация на AOT за настолни операционни системи — „шестият проблем с най-висок рейтинг“ в нашия инструмент за проследяване на проблеми – така че се радваме, че можем да предоставим тази функция.

Ако сте използвали dart2aot преди, тогава от 2.6 ще използвате dart2native. Той предоставя надмножество от функционалностите на dart2aot.

Изграждане на приложения за команден ред с dart2native

Компилаторът dart2native е чудесен избор за изграждане и внедряване на базирани на Dart приложения за командния ред. Тези приложения често използват библиотеки като dart:io (основен I/O), package:http (мрежова работа) и package:args (анализ на аргументи). Нека прегледаме основите на компилирането на приложение „hello, world“ в изпълним файл:

Изходният код hello.dart:

main() {
  print(‘Hello Dart developers’);
}

Компилирайте hello.dart в hello изпълним файл:

$ dart2native src/hello.dart -o hello
Generated: /Users/mit/hello

Стартирайте hello за измерване на времето за изпълнение:

$ time ./hello
Hello Dart developers
real 0m0.049s
user 0m0.018s
sys 0m0.020s

Забележете как командата стартира, отпечатва в stdout и излиза за общо време от само 49 милисекунди!

Видяхме няколко разработчици на Dart, които вече експериментират с dart2native за инструменти на командния ред:

  • Натали от екипа на SASS (популярен инструмент за разширение на CSS) съобщава, че след превключването на тяхната базирана на Dart SASS реализация към компилиране с dart2native, тя вече е конкурентна по отношение на производителността на LibSass, C++ базирана реализация.
  • Филип от екипа на Dart DevRel прекомпилира своя инструмент linkchecker с dart2native и видя 27x ускорение при проверка на малки сайтове.

Оперативна съвместимост с C код чрез dart:ffi

Местните приложения често се нуждаят от достъп до естествена функционалност от заобикалящата ги операционна система. Тези системни API обикновено се показват в собствени C-базирани библиотеки и Dart поддържа оперативна съвместимост с тези библиотеки чрез dart:ffi, нашия нов механизъм за C interop, който стартирахме в предварителен преглед в Dart 2.5. Компилаторът dart2native е съвместим с dart:ffi, така че можете да създавате и компилирате естествено Dart приложения, които го използват.

Един член на екипа наскоро използва dart:ffi, за да създаде dart_console библиотека за разработка на конзолни приложения, която има функционалност като получаване на размери на прозорец, четене и настройка на местоположението на курсора, управление на цветове и четене на клавиши и контролни последователности. Възможността да се използва dart:ffi прави Dart много мощен език за конзолни приложения.

kilo: 7MB кодов редактор, написан на по-малко от 500 реда Dart код

Използвайки основните библиотеки на Dart, dart:ffi и библиотеката dart_console, можем да създадем доста интересни конзолни приложения. Пакетът dart_console включва пълна демонстрация на kilo, конзолен текстов редактор, написан само на ~500 реда код на Dart. Името kilo идва от неговия произход, kilo.c, което беше реализация на C в приблизително 1000 реда код.

С новия компилатор dart2native можем лесно да пакетираме това и в крайна сметка получаваме 7MB самостоятелен редактор на код. Ето демонстрация на компилиране на редактора и след това използване на компилирания редактор, за да редактирате собствения си изходен код, за да коригирате грешка:

Изграждане на услуги с dart2native

Друга потенциална употреба на компилатора dart2native е за малки услуги - например бекенд, поддържащ приложение за преден край, написано с помощта на Flutter. През последните години нарастваща тенденция е използването на услуги, работещи на „безсървърни компютри“. Това са напълно управлявани услуги, които автоматично се мащабират, включително мащабиране от и надолу до нула (не работят), предоставяйки потенциал за значително по-ниски разходи, тъй като се таксуват само когато действително работят. Google Cloud прави изчисления без сървър достъпни чрез Cloud Run.

За бекенда без сървър е изключително важно услугата да стартира бързо. Традиционно услугите, базирани на Dart, се изпълняват с нашия компилатор JIT (точно навреме), но изпълнението, базирано на JIT, има голямо забавяне при стартиране, тъй като кодът трябва да бъде компилиран и загрят, преди да може да започне да се изпълнява. Като компилирате предварително кода на услугата си в естествен код, можете да избегнете това забавяне и да започнете да работите веднага. В допълнение, с естествен код можете да създавате услуги на Dart, които имат малък дисков отпечатък и са самостоятелни, което значително намалява размера на контейнера, в който се изпълнява услугата Dart. Разработчикът на Dart Paul Mundt наскоро документира своя опит с използването на компилатора dart2native; той успя да намали размера на своя Docker образ с 91% от 220MB с помощта на JIT-компилиран код до само 20MB с помощта на естествен код! Вижте нашата документация за повече подробности относно сървърните приложения и пакетите.

Наличност

Компилаторът dart2native е наличен в Dart SDK, започвайки с версия 2.6, която е достъпна от днес от dart.dev/get-dart. След като инсталирате SDK, трябва да видите новия компилатор в директорията bin/ и във вашия PATH. Dart.dev има повече документация.

Ако получавате Dart SDK чрез Flutter, имайте предвид, че текущите компилации на Flutter имат непълна поддръжка на dart2native. Препоръчваме ви да инсталирате Dart 2.6 SDK от dart.dev/get-dart.

Известни ограничения

Тази първоначална версия на компилатора dart2native има няколко известни ограничения, изброени по-долу. Можете да ни уведомите кои проблеми са важни за вас, като добавите „палец нагоре“ към проблема в нашия инструмент за проследяване на проблеми в GitHub.

  • Няма поддръжка за кръстосано компилиране (проблем 28617): Компилаторът dart2native поддържа създаване на машинен код само за операционната система, на която работи. По този начин ще трябва да стартирате компилатора три пъти - на macOS, Windows и Linux - ако искате да създадете изпълними файлове и за трите. Един от начините да направите това е чрез използване на доставчик на CI (непрекъсната интеграция), който поддържа и трите операционни системи.
  • Няма поддръжка за подписване (проблем 39106): Произведените изпълними файлове използват формат, който не е съвместим със стандартни инструменти за подписване като codesign и signtool.
  • Няма поддръжка за dart:mirrors и dart:developer (вижте Ядрени библиотеки на Dart).

Други промени в Dart 2.6

Версия 2.6 на Dart SDK също има няколко други промени.

Пуснахме предварителен преглед на dart:ffi, нашия нов механизъм за C interop, в Dart 2.5. Dart 2.6 има нова версия на dart:ffi. Тази нова версия има редица неработещи промени в API, за да направи нашите API по-лесни за използване, да осигури повече безопасност на типа и да осигури удобен достъп до паметта. За допълнителни подробности вижте Детлог на промените на Dart 2.6. С тези промени dart:ffi преминава към бета версията и очакваме промените в API да бъдат много по-рядко занапред и общата стабилност се очаква да бъде висока. Моля, продължете да ни давате обратна връзка чрез проследяване на проблеми.

Dart 2.6 също съдържа предварителен преглед на вълнуваща нова функция на езика, методи за разширение. Имаме още малко работа по лакиране и инструменти, за да завършим тази функция, но се надяваме да я стартираме официално в следващата ни версия на Dart SDK. Тогава ще имаме много повече да кажем за методите за разширение; засега можете да прочетете за дизайнерските съображения зад функцията.

Следващи стъпки

Изтеглете Dart 2.6 SDK (dart.dev/get-dart), създайте нещо страхотно с dart2native и след това ни разкажете за него. Ако желаете да споделите подробностите, моля, оставете отговор в долната част на тази статия. Вълнуваме се да видим какво създавате!