原文作者:medium.com/@mit.mit
发布时间:2019年11月6日 - 6分钟阅读
Dart已经提供了一套广泛的编译器,用于为移动设备和网络构建生产优化的代码。这些灵活的编译器使我们的框架合作伙伴能够针对广泛的形式因素。Android和iOS上的Flutter应用,Web和桌面上的Flutter应用,Web上的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的机器上运行。因为它们是用Dart的AOT编译器编译的,所以可执行文件只需几毫秒就可以开始运行。与其他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扩展工具)团队的Natalie报告说,在将他们基于Dart的SASS实现转换为使用dart2native编译后,现在它的性能已经可以和基于C++的LibSass竞争了。
- Dart DevRel团队的Filip用dart2native重新编译了他的linkchecker工具,在检查小型网站时,速度提高了27倍。
通过dart:ffi与C代码的互操作性
本机应用程序经常需要访问周围操作系统的本机功能。这些系统API通常暴露在基于C的原生库中,Dart通过dart:ffi支持与这些库的互操作性,dart:ffi是我们在Dart 2.5预览版中推出的新的C互操作机制。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,它是用大约1000行代码实现的C语言。
有了新的dart2native编译器,我们可以很容易地将其打包,最终我们得到了一个7MB的独立代码编辑器。下面是一个编译编辑器的演示,然后用编译后的编辑器编辑自己的源代码来修复一个bug:
用Dart编写的kilo编辑器,并编译成可执行文件,由dart2native编辑自己的源代码。
用dart2native构建服务
dart2native编译器的另一个潜在用途是用于小型服务--例如,支持使用Flutter编写的前端应用的后端。近年来,一个不断增长的趋势是使用在无服务器计算上运行的服务。这些是完全托管的服务,可以自动扩展,包括从零扩展到零(不运行),提供了大大降低成本的潜力,因为它们只在实际运行时计费。谷歌云通过Cloud Run提供无服务器计算。
对于无服务器后端来说,服务的快速启动是至关重要的。传统上,基于Dart的服务都是使用我们的JIT(just-in-time)编译器运行的,但基于JIT的执行在启动时有很高的延迟,因为代码需要在开始执行前进行编译和预热。通过提前将服务的代码编译成原生代码,您可以避免这种延迟,并立即开始运行。此外,使用原生代码,你可以创建磁盘占用空间小、自成一体的Dart服务,大大减少Dart服务运行的容器的大小。Dart开发者Paul Mundt最近记录了他使用dart2native编译器的经验;他能够通过使用原生代码将他的Docker镜像的大小减少91%,从使用JIT编译代码的220MB减少到只有20MB。请参阅我们的文档,了解更多关于服务器端应用和包的细节。
可用性
dart2native编译器从2.6版本开始就可以在Dart SDK中使用了,今天就可以从dart.dev/get-dart中获得。一旦你安装了SDK,你应该会在bin/目录和PATH中看到新的编译器。Dart.dev有更多的文档。
如果你是通过Flutter获得Dart SDK,请注意当前的Flutter构建有不完整的dart2native支持。我们建议你从dart.dev/get-dart安装Dart 2.6 SDK。
已知的限制
这个dart2native编译器的初始版本有一些已知的限制,下面列出。你可以通过在GitHub问题跟踪器中添加 "大拇指 "来让我们知道哪些问题对你很重要。
- 不支持交叉编译(问题28617)。dart2native编译器只支持为其运行的操作系统创建机器代码。因此,如果你想为这三个系统创建可执行文件,你需要在macOS、Windows和Linux上运行三次编译器。一种方法是使用支持这三种操作系统的CI(持续集成)提供商。
- 不支持签名(问题39106)。产生的可执行文件使用的格式与标准签名工具不兼容,如
codesign和signtool。 - 不支持
dart:mirrors和dart:developer(见Dart核心库)。
Dart 2.6中的其他变化
2.6版本的Dart SDK还有一些其他变化。
我们在Dart 2.5中推出了dart:ffi的预览版,这是我们新的C语言互操作机制。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构建一些很酷的东西,然后告诉我们。如果你愿意分享细节,请在本文底部留言。我们很高兴看到你的作品。
通过( www.DeepL.com/Translator )(免费版)翻译