使用Bakeware将Elixir应用程序编译为单个可执行的二进制文件

2020-10-23 02:54:54

BAKWARE是一个新的奇妙的工具,是在一个周末为SpawnFest 2020而构建的,它将一个药剂、一个风景或一个凤凰应用程序编译成单一的可执行二进制文件(是的,就像Go-Lang!)。分发我们的应用程序非常有用,特别是当它们是命令行工具或Scen应用程序时。

对于大多数Phoenix应用程序部署来说,这个工具可能并不重要,但我认为有时候拥有一个Phoenix/Phoenix LiveView应用程序(以及所有需要的资产)可能真的很有用!以单一且易于共享的二进制形式。

让我们看看如何在Phoenix LiveView应用程序中使用它。我们将要看到的也适用于CLI和Scene应用程序。

目前在https.pm上还没有官方的库,所以让我们首先从它的GitHub repo,spawnfest/bakeware下载Bakeware的代码。

$git将https://github.com/spawnfest/bakeware.gitCloning克隆到';BAKWARE';.$ls BAKEWARE/BAKEWARE生成文件自述文件.md资产库混合.exs混合.lock源测试。

在BAKWARE/Examples文件夹中,您还可以找到其他有用的示例。我们需要的库代码位于bakeware/bakeware目录中。

要查看Bakeware的运行情况,让我们创建一个名为Counter的新Phoenix项目,该项目支持LiveView,但不支持ecto。

在计数器Phoenix项目的目录中,我们创建了一个lib/count_web/live/counter_live.ex文件,我们在其中定义了一个CounterWeb.CounterLive实时视图。您可以简单地复制/粘贴下面的模块代码。

会话计数器:#lib/counter_web/live/counter_live.exdefmodule_VIEW@Iml true def mount(_params,_Session,Socket)do{:OK,Assign(Socket,Counter:0)}End@Impl true def Render(Assigns)do~L";";";<;h1<;计数器:<;%=@Count%gt;<;/h1>;<;按钮phx-click=";dec";>;-<;/button>;<;button phx-click=";inc";>;+<;/button>;";";";end@impl true def handle_event(";inc&34;,_,socket)do{:无回复,更新(套接字,:计数器,&;&;1+1)}end@impl true def Handle_event(";Dec";,_,Socket)do{:无回复,更新(Socket,:Counter,&;&;1-1)}endend。

#lib/count_web/router.exdefmodule CounterWeb.Router Do Use CounterWeb,:Router...。范围";/";,CounterWeb do PIPE_THROUGH:Browser LIVE";/";,CounterLive,:index End。

好了,我们现在有了一个简单的LiveView计数器应用程序,可以用Bakeware编译。

要使用BAKWARE WE,只需更改计数器Phoenix项目的Mix.exs文件。

#Mix.exsdefmodule Coun.MixProject do def project do[APP::Counter,...。发布:[baked_counter:[Steps:[:Assemble,&;Bakeware.Assembly/1],strie_ams:Mix.env()==:prod,overwrite:true]]End Defp Alias do[Assets:[";cmd NPM run Deploy--Prefix Assets";],Release:[";Assets";,";phx.digest";,";Release";],Setup:[";Deps.Get";],Release:[";Assets";,";phx.digest";,";Release";],Setup:[";Deps.Get";];,";cmd NPM安装--prefix sets";]]end defp deps do[...{:bakeware,path:";../bakeware/bakeware";,run:false}]endend。

我们首先添加:bakeware依赖项,将:path指向本地bakerware子文件夹,并将:runtime选项设置为false。

然后,我们添加:Release和:Assets别名,它们缩短了构建发行版所需键入的命令列表。例如,:release别名运行Mix Assets、Mix phx.digest和Mix Release。

最重要的是,我们在project/0返回的关键字列表中添加了:release选项。我们构建的唯一版本名为baked_counter,并且我们将[:Assemble,&;Bakeware.Assemble/1]设置为组装版本时要执行的步骤列表。我们设置了另外两个选项:overwrite:true(如果有现有的发布版本,则将其覆盖)和:strie_beams,仅当环境为PROD时才为true(控制是否应该删除BEAM文件的调试信息、文档块和其他不必要的元数据)。

当设置SERVER:TRUE时,Web服务器在端点监控树启动时启动。我们还可以添加CHECK_ORIGURCE:FALSE,这将禁用对源头的检查。

我们已经准备好构建版本了。在运行混合任务之前,我们需要加密_KEY_BASE环境变量。

然后,我们运行安装和发布混合任务,将MIX_ENV环境变量设置为PROD。

$MIX_ENV=生产混合设置...$MIX_ENV=生产混合版本...*正在组装烘焙软件BAKED_COUNT BAKWARE已成功汇编可执行文件\at_build/prod/rel/bakeware/baked_counter。

当我们运行它时,我们看到我们的服务器正确启动,为Web应用程序资产(在本例中只有javascript、CSS和Phoenix Framework徽标)提供服务。

$./_build/prod/rel/bakeware/baked_counterbakeware:启动';/Users/alvise/Documents/poeticoding/bakeware/code/counter/./_build/prod/rel/bakeware/baked_counter';(cachedir=/Users/alvise//Library/Caches/Bakeware)...bakeware:缓存无效。正在解压...烘焙软件:运行/Users/alvise//Library/Caches/Bakeware/6ea5f818ebb68300b8d953d54e082779006802152906cd90dc43caeaefc9a19f/start...16:49:25.455[INFO]运行计数器Web.Endpoint,牛仔2.8.0位于:4,000(HTTP)16:49:25.456[INFO]访问计数器Web.Endpoint位于http://example.com。

由Bakeware构建的可执行二进制文件将整个发行版压缩在其中。当我们运行它时,它会提取缓存文件夹中的所有内容,并启动应用程序。

为了优化启动时间,Bakeware维护提取的二进制文件和资源的缓存。这样,我们第二次运行它时,速度会更快,因为它不需要解压缩任何东西。

在这种情况下,我用的是Mac电脑。如果我们进入~/Library/Caches/Bakeware/6ea5f...。文件夹,我们找到解压的版本。

让我们在另一台Mac上尝试一下baked_counter。如果您的应用程序是在Linux上构建的,那么它应该可以在其他类似的Linux环境下运行。Windows支持即将到来(请看本文末尾)。

我是用我的MacBook Pro和Catalina(10.15.7)编译的,所以看看它是否能在稍微老一点的MacOS版本上运行会很好,比如Mojave(10.14)。我没有另一台Mac,所以我使用MacOS10.14的远程Macmini,由MacinCloud托管,实行现收现付计划。

它成功了!!它是否兼容多种操作系统版本?Well…。这取决于不同的东西。当我们构建一个发行版时,这应该运行在具有相同操作系统和类似环境的目标机器上,比如C运行时和Erlang运行时引用的其他库,以及应用程序中的任何NIF和端口。

这是一个刚开始一个月的项目,团队计划做很多其他的事情,例如:

你认为烘焙用品会对你有帮助吗?也许是为了用长生不老药写的CLI?或者是带有LiveView的风景或凤凰应用程序?让我知道你的想法!