RUST 是 JavaScript 基建的未来

12,571 阅读9分钟

翻译自《Rust Is The Future of JavaScript Infrastructure》,网址:Rust Is The Future of JavaScript Infrastructure – Lee Robinson

作者是:Lee Robinson。

Rust 是一个快速、可靠、节约内存的编程语言。在过去六年的 stackoverflow 的最受喜爱的编程语言(201620172018201920202021)中,连续得到榜首的位置。Mozilla 创造了 Rust,Facebook、Apple、Amazon、Microsoft 和 Google 都使用 Rust 去开发系统基础设施、加密、虚拟化以及其他的层级较低的软件。

为什么 Rust 开始替换 Javascript 的 Web 生态系统的重要组成部分包括压缩(Terser)、编译(Babel)、格式化(Prettier)、打包(webpack)、代码检查(ESLint)、以及更多其他的库?

Rust 是什么?

Rust 帮助开发者开发节约内存的快速软件。它是同样关注代码安全、简洁语法的 C++ 或者 C 的一种现代的替换选择。

Rust 和 JavaScript 非常不一样。JavaScript 会去找到不用的变量和对象,然后自动清除它们。这个机制叫做垃圾回收(Garbage Collection)。Rust 则希望开发者自己去规划手动的内存管理。

通过使用 Rust,开发者对于内存可以有更大的控制权,使用上则比 C++ 或者 Go 要少一些痛苦。

Rust 使用了一种非常独特的内存管理手段,其核心理念基于 “所有权”(owernership)。基本上,Rust 会追踪“谁”在读和写具体的一块内存。Rust 知道一块内存是谁在使用,也知道这块内存是否已经没人使用,这时可以立即释放这块内存。Rust 在编译时强制内存规则,这个机制让内存 bug 几乎不会存在于运行时(runtime)。你不需要手动追踪内存,编译器会帮你处理好。 --Discord

Adoption

除了在上面提到过的使用 Rust 的公司,Rust 也被很多流行的开源库使用:

Rust 让我们力量倍增,使用 Rust 是我们做的最好的决策之一。除了性能,Rust 关注正确性的工程哲学帮助我们更好的掌控复杂度。我们可以使用 Rust 的类型系统编写复杂的变量,然后让 Rust 的编译器帮我们做检查。 --Dropbox

从 JavaScript 到 Rust

JavaScript 是最广泛应用的编程语言,在每一台有浏览器的设备上运行着。在过去十年,围绕着 JavaScript 建立了一个非常巨大的生态系统。

  • Webpack: 帮助开发者把多个 JavaScript 文件打包成一个。
  • Babel: 帮助开发者使用现代 JavaScript 语法编写支持老式浏览器的程序。
  • Terser: 帮助开发者压缩生成的代码(用以节省流量和混淆)。
  • Prettier: 帮助开发者统一格式化所有的代码。
  • ESLint: 帮助开发者在编写代码时自动找出潜在的问题。

像这样的库还有很多,成千上万的代码以及更多的被修复的 Bug,都成为了当今 Web 应用程序得以顺利运行的基石。这个工具都使用 JavaScript 或者 TypeScript 编写。这个机制运行的是 OK 的,但是我们遇到了 JS 的优化峰值。新一代工具使用了更高效的设计,影响着以前的工具。

SWC

SWC,创建于 2017 年,目标是提供一个可扩展的基于 Rust 的致力于制造下一代快速开发工具的平台。这个工具被一些知名项目使用,比如 Next.js、Parcel 和 Deno,还有一些公司也在使用他,包括 Vercel, ByteDance, Tencent, Shopify。

SWC 可以用来编译、压缩、打包,还可以使用插件提供的功能。你可以用这些功能来做代码变换。上面提到的高级工具,比如 Next.js 也在跑着这些变换。

Deno

Deno,创建于 2018 年,是一个简单、现代、安全的 JavaScript 和 TypeScript 的运行时。Deno 使用了 V8 以及使用 Rust 开发。Deno 的创始人是 Node.js 的创始人,它企图替换 Node.js。Deno 在 2020 的五月发布了 1.0 版本。

Deno 的代码审查器、代码格式器、文档生成器都使用 SWC 建造。

esbuild

esbuild,创建于 2020 年 1 月,它是一个用 go 编写的 JavaScript 打包器,比现存的其他工具快 10-100 倍。

我在尝试建造一个建造工具:A)在特定的使用场景(打包 JavaScript、TypeScript、也许还有 CSS)使用良好 B)重置开发者社区对于 JavaScript 建造工具速度的期望值。我们现在的工具实在太慢了。 --Evan, esbuild 作者 ( Source )

使用系统编程语言、例如 Go 或者 Rust,来建造 JavaScript 的工具,在 esbuild 发布时,还是比较稀少的。个人观点,esbuild 启发了非常一大批工具开发者使用系统编程语言,让这些工具变得更快。Evan 选择使用 go:

用 Rust 编写的话,如果给予一定的努力,应该可以运行的也挺好。但是在一个更高的层级,Go 使用起来更有舒服。这个项目对我来说只是一个副业项目,所以它必须有趣。 – Evan, esbuild 作者( Source )

有一些人认为,Rust 可以表现的更好,但是两者都可以实现 Evan 的目标,以及去影响社区:

即便使用非常基本的优化,Rust 也能比 Go 优化最好的表现要好。用 Rust 写高性能程序比研究非常高深 Go 要简单的多。 Discord

Rome

Rome, 创建于 2020 年 8 月,是一个可以用来针对 JavaScript、TypeScript、HTML、JSON、Markdown 和 CSS 的代码检查器、编译器、打包器、测试器、以及更多的功能。Rome 的愿景是替换和统一前端开发的工具链。它的作者叫Sebastian,他也开发了 Babel。

为什么要开发所有东西?

为了让 Babel 可以作为其他工具的底层基石,要做一些必要的改变,这些改变基本上要完全调整 Babel 的架构。Babel 的架构是我在 2014 年正在学习解析器、语法树、编译器的时候做的。 - Sebastian ( Source )

Rome 使用 TypeScript 编写,可以跑在 Node.js 上,但是现在正在用 Rust 重写。

Rust + WebAssembly

WebAssembly (WASM) 是一种 Rust 可以编译到的便携低级语言。WASM 跑在浏览器里,可以和 JavaScript 互相调用,几乎所有现代浏览器都支持。

WASM 比 JS 快的多,但是没有原生开发速度快。我们测试来看,Parcel 使用 WASM 比原生开发慢 10-20 倍。 Devon Govett

WASM 还不是目前最完美的方案,但是依然可以帮助开发者提供更快的体验。Rust 官方已经承诺更高质量的 WASM 实现。对于开发者来说,意味着你可以享受到 Rust 的性能(相比于 Go),即便你仍然编译到 Web 上(使用 WASM)。

以下是目前比较早期的库和框架:

这些基于 Rust 的 web 框架,虽然编译到 WASM 但是并不计划去替换 JavaScript,而是选择与 JavaScript 共生。这是我们乐意见到的:Rust 即让 JavaScript 的功能更快,也能实现面向未来的编译到 WASM

一路都是 Rust。

为什么不用 Rust?

Rust 有非常陡峭的学习曲线。Rust 的抽象层级要比绝大部分 Web 语言低。

Rust 让你思考你的代码的方方面面,这对于系统开发是极为重要的。Rust 强制你思考内存是如何共享和拷贝的。Rust 强制你思考少见但是真实的边缘场景,以确保这些边缘场景也被控制住了。在任何能提升你效率的地方,Rust 都会帮你。 – Tom MacWright ( Source )

Rust 在 Web 社区的使用还是很稀少的。还没被大规模应用。尽管对于 JavaScript 的工具制造者们,学习 Rust 是一个障碍。但是有趣的是,开发者们宁愿使用更快的工具,哪怕他们更难去贡献代码(因为 rust 更难)。更快的软件最终获得胜利。(天下武功唯快不破)

目前,还是很难找到 Rust 的库去做大家喜欢的服务(比如鉴权、数据库、交易等等)。但是我认为,当 Rust 和 WASM 大规模应用以后,这些问题会自己解决的。但是不是现在。我们需要 JavaScript 工具帮助我们搭建一个桥梁,然后慢慢改进性能问题。

JavaScript 工具的未来

我相信,Rust 是 JavaScript 工具的未来。Next.js 12 开始全面使用 SWC 和 Rust 替换 Babel(编译器)和 Terser(代码压缩器)。为什么呢?

  • 扩展性: SWC can be used as a Crate inside Next.js, without having to fork the library or workaround design constraints.
  • 性能: 通过使用 SWC,我们获得了 3 倍的刷新速度和 5 倍的打包速度,而且性能提升仍然有很大的空间。
  • WebAssembly: Rust 支持 WASM,对于所有平台都可以支持,也可以带 Next.js 到任何地方。
  • Community: Rust 社区和生态系统非常惊人,还在持续增长。

不仅是 Next.js 使用 SWC,还有:

  • Deno’s 的代码审查器、格式器、文档生成器都使用 SWC
  • Rome 正在使用 Rust 重写,计划使用SWC。
  • dprint, 使用 SWC创建,比 Prettier 快 30x 倍。
  • Parcel 使用 SWC,改善了 10x 的性能。

Parcel 使用 SWC 就像用一个库。之前,我们使用 Babel 的解析器,用 JS 编写。现在我们使用 SWC 的解析器,用 Rust 编写。包括作用域提升的实现,依赖收集,还有其他。这个和 Deno 制造在 SWC 上面的原理一样。 Devon Govett

虽然这是 Rust 的早期使用,有一些重要的点还要在这里指出来:

  • 插件: 用 Rust 写插件对于大部分 JS 开发者还是比较难的事儿。用 JS 来制造插件体系,会有性能问题。这个问题目前还没有太好的解决方案。
  • 打包: 目前我们感兴趣的是 swcpack,这个是 webpack 的替代工具。虽然现在还在开发阶段,但是未来可期。
  • WebAssembly: 虽然使用 Rust 和编译到 WASM 看起来很诱人,但是目前还有大量工作需要做。

不管怎样,我对 Rust 会持续加大影响 JavaScript 生态圈这件事是无比自信的。想象一下全世界使用 Next.js 的项目在打包时已经得到 Rust 带来的性能好处。然后,你可以像其他 NPM 包一样,使用 Next.js。

这是我想生活(和开发)的世界。