前端工具Rome将用Rust改写


罗马是用来取代 BabelESLintwebpackPrettierJest,。Rome统一了以前是独立工具的功能。建立在共享基础上使我们能够为处理代码、显示错误、并行化工作、缓存和配置提供有凝聚力的体验。Rome以前是用TypeScript编写的,运行在Node.js 上。
 
为什么改用 Rust?
我们最关心的是我们自己的生产力。
最初很难想象一个由 JavaScript 开发人员组成的小团队能够在几周内掌握足够的专业知识来构建复杂的语言工具并提高工作效率。然而,经过一些原型设计之后,我们很快意识到我们实际上可能在 Rust 中更有效率。
Rome 早期的主要决定之一是不使用任何第三方依赖项——我们甚至用我们自己的封装了 Node API。这个决定是基于严格控制 Rome 内部所有代码的愿望,以便我们可以保证性能、内存使用和正确性/类型安全。
然而,其中许多问题在 Rust 及其社区中得到了解决:

  1. 对第三方依赖的权衡更少 大多数 JavaScript/npm 包都必须平衡许多不同类型用户的不同关注点。他们被迫围绕我们不感兴趣的代码大小和性能进行权衡。另一方面,Rust crate 通常会做出更接近我们需求的权衡。
  2. 正确性内置于标准库和大多数流行的 crate 中。 我们正在创建自己的 API,专注于正确性,而不是使用第三方 JavaScript 依赖项。Rust 及其社区更加关注正确性,而没有为罗马需要担心的边缘情况铺平道路。
  3. Trait/Module 系统允许我们更好地利用依赖关系 Rust 的 trait 系统是一种强大的方式,可以在没有开销的情况下创建对任何数据的抽象。它允许我们深度集成第三方库。它还允许库创建增量更多的 API,安全地暴露更多的表面积,而无需进行重大更改。

我们意识到,在 Rust 中工作时,我们避免第三方依赖的原因并不适用。能够在不进行权衡的情况下建立高质量的依赖关系使我们更有效率,并将导致更好、更快的Rome 。
 
改变的地方
当我们开始在 Rust 中进行原型设计并重新审视我们的许多基本设计决策时,这也为我们提供了重新审视我们架构的机会。很快,我们意识到我们想要做出一些非常大的改变。
如果您曾经花时间学习编译器的工作原理,那么您可能听说过以下内容:
  1. 源代码→词法分析→标记
  2. 标记→句法分析→抽象语法树
  3. 抽象语法树→各种变换→一些中间表示
  4. 一些中间表示→代码生成→ { Machine,Byte,Source} 代码

这是编译器如何工作的一个很好的高级心理模型,但大多数编译器比这复杂得多。
很快你就会想要一些东西:
  • 在开发人员进行代码更改时增量构建项目。
  • 在编译器完成工作之前请求有关某些代码的信息。
  • 即使代码包含语法错误,也要继续提供反馈。

对于 JavaScript 和 Web 社区来说,这些责任通常被分配到许多不同的工具之间,这导致每个人一遍又一遍地以略有不同的方式实现相同的东西。Rome 希望同时成为所有这些工具,因此我们需要一个适用于所有这些不同工具的基础。
我们研究了其他较新的编译器是如何解决这些问题的。我们很快意识到的一个关键问题是我们对抽象语法树 (AST) 的处理方法。

更多点击标题