Elixir v1.13发布|API的改进

128 阅读7分钟

Elixir v1.13刚刚发布!

一般来说,新的Elixir版本包括对其主要API的改进,即Elixir开发人员每天都在使用的API,同时也包括为其工具提供动力的基础。然而,在这个版本中,恰好大多数新功能都是围绕Elixir工具的。其结果是一系列生活质量的改进,这些改进将立即影响Elixir开发人员,并在长期内产生影响。

让我们来看看它们吧

注意:本公告包含asciinema片段。你可能需要在这个网站上启用第三方的JavaScript,以便看到它们。如果JavaScript被禁用,将显示带有适当链接的noscript 标签。

语义重新编译

最能让所有Elixir开发者立即受益的功能是我们对编译器跟踪文件内容的方式进行了一系列改进。

一般来说,一旦一个文件发生变化,就可能导致你代码库中的其他文件被重新编译。然而,在以前的版本中,Elixir没有努力去了解文件的哪些部分发生了变化。这意味着某些文件的最小变化,如配置文件,都可能触发整个项目的重新编译。

这个版本有一系列的改进,可以更好地理解你的文件如何变化。特别是。

  • 如果一个Elixir文件的大小和摘要保持不变,它就不再被认为是改变了。这就避免了在切换或重新安置分支时重新编译许多文件。

  • 改变你的mix.exs ,将不再触发整个项目的重新编译,除非你特别改变Elixir编译器使用的配置(:elixirc_paths:elixirc_options)。

  • 改变编译时的配置文件 (config/config.exs 以及从它导入的任何其他文件) 现在只重新编译依赖于重新配置的应用程序的项目文件,而不是完整的项目重新编译。然而,如果你改变了你的应用程序本身的配置,整个项目仍然被重新编译。

  • 添加、更新或删除一个依赖项,现在只重新编译依赖于修改后的依赖项的项目文件。

  • 如果你的项目同时有Erlang和Elixir文件,改变一个Erlang文件现在将只重新编译依赖它的Elixir文件。

简而言之,Elixir从过去每当mix.exs,config/config.exs,src/*,mix.lock 中的任何一个在磁盘上发生变化时都会触发完全的重新编译,变成了语义上的重新编译。现在,它只在以下情况下进行完全重新编译。

  • 你改变了 "Dreams "中的编译选项mix.exs
  • 中改变了当前项目的配置。config/config.exs

为了给出一个更实际的例子,以一个普通的Phoenix项目为例。它很可能被分为两个主要目录:my_appmy_app_web 。你对Phoenix的API的大部分使用将发生在my_app_web 目录下的文件中。然而,如果你在以前的Elixir版本中提升了你的Phoenix版本或改变了它的配置,它将导致所有的文件,在这两个目录中,被重新编译。有了这些变化,重新编译应该主要影响my_app_web 中的文件。

为了进一步澄清,Elixir编译器并不是在追踪目录。这只是Phoenix项目组织方式的一个结果,对Phoenix的大多数依赖都在my_app_web

代码片段

Code模块有一个配套的模块叫 Code.Fragment.

Code 模块使用完整的代码工作。例如,它的函数会认为123 + 这个片段是无效的,因为+ 的右侧缺失。然而,我们的工具,如编辑器、REPL和代码笔记本仍然必须解析和理解这些代码片段,以便提供代码补全、参数建议等。

这就是Code.Fragment 模块的目标。它包含不同的启发式方法来分析和返回代码片段的上下文信息,这些代码片段可能是不完整的。

为了更好地展示上述改进的好处,让我们来谈谈IEx,Elixir的交互式外壳。IEx已经被重写,以使用Code.Fragment ,在这个过程中,它获得了新的功能,作为其自动完成系统的一部分(可通过点击TAB)。例如,它现在可以自动完成符号,用于创建词组单词列表,以及它们的终止符。

见asciinema中的例子

同样地,你现在可以自动完成结构名称和它们的字段。

见asciinema中的例子

总的来说,我们希望Code.Fragment 模块将成为共享的基础,为生态系统中的许多工具提供动力。我们还向.NET添加了新的反射API。 Module我们还向.NET添加了新的反射API,这些API可以用来支持代码智能功能。

混合xref

mix xref是一个分析文件之间关系的工具。通过分析它们之间的编译时和运行时的依赖关系,它可以让开发者了解每当文件发生变化时,哪些东西必须重新编译。

Elixir v1.13对mix xref ,有很多改进,比如。

  • mix xref graph 现在支持将 设置为 "compile-connected",这将返回所有导致额外横向依赖的编译时依赖。--label

  • 一个新的mix xref trace FILE 子命令接收一个文件并返回该文件中的所有依赖关系,包括该行和导致该依赖关系的原因(一个函数/宏调用,一个别名,一个结构,等等)。

  • 所有mix xref 子命令都支持--fail-above 标志,它允许你强制执行你的项目最多只有一定数量的编译时周期,反式编译时依赖等。这在持续集成(CI)服务器上很有用。

  • mix xref graph 现在支持给出多个 和 。--sink --source

如果你以前没有使用过mix xref ,可能很难想象这些变化意味着什么。如果你想了解更多,你可以观看我的ElixirConf 2021主题演讲的相关部分,其中包括对mix xref 的简短介绍。

这些改进来自于社区的直接反馈。在此特别感谢Marc-André Lafortune的贡献和测试。

扩展的代码格式化

由于它的符号,Elixir提供了在其源代码中嵌入其他语言的片段的能力。人们可以用它来嵌入XML。

~X"""
<?xml version="1.0" encoding="UTF-8"?>
<text><![CDATA[Hello World]]></text>
"""

甚至是Zig通过Zigler项目

~Z"""
/// nif: example_fun/2
fn example_fun(value1: f64, value2: f64) bool {
  return value1 > value2;
}
"""

然而,虽然你可以用Elixir源代码格式化 mix format,但你无法格式化片段内的代码。

Elixir v1.13通过向mix format 添加插件解决了这个问题。插件可以通过Mix.Tasks.Format 行为,教格式化器如何格式化新文件和如何格式化sigils。

例如,设想你的项目以两种不同的方式使用Markdown:通过一个自定义的~M sigil和通过带有.md.markdown 扩展名的文件。一个自定义的插件将看起来像这样。

defmodule MixMarkdownFormatter do
  @behaviour Mix.Tasks.Format

  def features(_opts) do
    [sigils: [:M], extensions: [".md", ".markdown"]]
  end

  def format(contents, opts) do
    # logic that formats markdown
  end
end

现在任何应用程序都可以使用你的格式化器,如下所示。

# .formatter.exs
[
  # Define the desired plugins
  plugins: [MixMarkdownFormatter],
  # Remember to update the inputs list to include the new extensions
  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}", "posts/*.{md,markdown}"]
]

我们期待着看到社区将如何使用这个新功能,特别是像SurfacePhoenix LiveView这样的项目,它们在HTML标记之上提供了一种模板语言。

其他比特和字节

SyntaxError 和 ,以尽可能地显示代码片段。TokenMissingError

$ elixir -e "hello + * world"
** (SyntaxError) nofile:1:9: syntax error before: '*'
    |
  1 | hello + * world
    |         ^

Code 模块也增加了两个功能。 Code.string_to_quoted_with_comments/2Code.quoted_to_algebra/2.这些函数允许某人检索带有原始源代码注释的Elixir AST,然后将这个AST转换成格式化的代码。换句话说,这些函数为Elixir代码格式化器提供了一个包装,支持那些希望创建直接操作和自定义格式化Elixir源代码的工具的开发者。

elixir --short-version 增加了快速获取Elixir版本的功能,无需启动Erlang VM。 模块包括性能优化和Task 函数。最后,添加了 ,以调试测试套件的加载时间,最近添加的mix test --profile-require=time Mix.install/2已经通过新的选项和环境变量进行了改进。

了解更多

关于所有变化的完整列表,请看完整的发布说明。你也可以观看我在2021年ElixirConf上关于Elixir v1.13的主题演讲来了解更多。

查看安装部分以获得Elixir的安装,并阅读我们的入门指南以了解更多。

祝你玩得开心!