查看原文
其他

Rust 才是 JavaScript 基础设施的未来

前端大全 2022-07-13

The following article is from ByteDance Web Infra Author sinoon

本文翻译自:Rust Is The Future of JavaScript Infrastructure – Lee Robinson[1] ,已获得作者授权,原文略做修改以符合中文语境。

(图片镇楼,与原文无关)

Rust[2] 是一种快速、可靠、内存高效的编程语言。它已经连续六年被评为最受 [3] [4] 的 [5] [6] [7] [8] 。它由 Mozilla 创建,现在被 Facebook[9] 、 苹果[10] 、 亚马逊[11] 、 微软[12] 和 谷歌[13] 用于系统基础设施、加密、虚拟化和更多底层(low-level)的编程中。

为什么Rust现在被用来取代 JavaScript 成为 Web 生态系统的一部分,如压缩(Terser)、编译(Babel)、格式化(Prettier)、打包(webpack)、linting(ESLint),以及其他场景?

什么是Rust?

Rust 帮助开发人员编写运行快并高效利用内存的软件。它是 C++ 或 C 等语言的现代替代品,聚焦在代码安全和简洁的语法。

Rust 与 JavaScript 有很大不同。JavaScript 采用的是 垃圾回收[14] 机制,会试图清除不再使用的变量和对象。JavaScript 将开发者从对手动内存管理的思考中抽离出来。

有了 Rust,开发者对内存分配有了更多的控制,而不像 C++ 或 Go 那样令人痛苦。

Rust 使用了一种相对独特的内存管理方法,包含了内存“所有权”的概念。基本上,Rust 会记录谁可以读取和写入内存。它知道程序什么时候在使用内存,一旦不再需要就立即释放内存。它在编译时执行内存规则,使得运行时的内存错误几乎不可能出现。你不需要手动跟踪内存。编译器会照顾到这一点。

—— Discord[15]

Adoption

在上面提到的公司之外,Rust 还被用于流行的开源库,比如:

  • Firecracker[16] (AWS)

  • Bottlerocket[17] (AWS)

  • Quiche[18] (Cloudflare)

  • Neqo[19] (Mozilla)

Rust 一直是我们团队的力量源泉,押注Rust是我们做出的最好决定之一。除了性能之外,它的人机工程学( ergonomics )和对正确性的关注也帮助我们控制了同步的复杂性。我们可以在类型系统中对系统的复杂不变性进行编码,让编译器为我们检查。

—— Dropbox[20]

从 JavaScript 到 Rust

JavaScript 是使用最广泛的编程语言,存在于每个有浏览器的设备上。在过去的十年中,围绕着 JavaScript 已经建立了一个庞大的生态系统:

  • Webpack :开发者希望将多个 JavaScript 文件 bundle 成一个文件。

  • Babel :开发者希望在支持旧版浏览器的同时编写现代 JavaScript 。

  • Terser :开发者希望生成尽可能小的文件。

  • Prettier :开发者希望有一个有自带规则(opinionated)的代码格式化器,刚好可用就行。

  • ESLint :开发者希望在部署前发现他们的代码存在的问题。

数以百万计的代码被编写出来,甚至更多的 bug 被修复,从而为今天的 Web 应用提供了基础。所有这些工具都是用 JavaScript 或 TypeScript 编写的。目前已经做的很不错了,但我们对 JS 的优化已经达到顶峰。因此,这激发了一类新的工具们的诞生,旨在极大地提高 Web 构建的性能。

SWC

SWC[21] 创建于 2017 年,一个下一代快速开发的工具,是一个基于 Rust 的可扩展平台。Next.js、 Parcel 和 Deno 等工具,以及 Vercel、字节跳动、腾讯、Shopify 等公司都在使用它。

SWC 可用于编译(compilation)、压缩(minification)、打包(bundling)等 —— 并且被设计成可扩展的。你可以调用它来执行代码转换(无论是内置的还是自定义的)。这些转换由更高维度的工具来运行,比如 Next.js 。

Deno

Deno[22] 创建于 2018 年,是一个简单、现代、安全的 JavaScript 和 TypeScript 的运行时,Deno 使用 V8[23] 的同时,并以 Rust 构建。它试图取代 Node.js ,由 Node.js 的原作者创建。虽然它是在 2018 年创建的,但直到 2020 年 5月才达到[24] v1.0[25] 。

Deno 的 linter、code formatter 和文档生成器是使用 SWC 构建的[26] 。

esbuild

esbuild[27] 创建于 2020 年 1 月,一个代码打包和压缩的工具,它是用 Go 写的,比当今的工具快 10 到 100 倍。

我试图创建一个构建工具:

A)能够在一个合理的场景(bundler JavaScript,TypeScript,也许还有CSS)中工作得很好。

B)能够重新定义社区对构建工具速度的期望。对于JS快速构建工具来说,到底什么才是快?在我看来,我们目前的工具都太慢了。

—— Evan,Creator of esbuild( Source[28] )

在 esbuild 发布之前,用系统编程语言(如 Go 和 Rust )构建 JavaScript 工具是相当小众的。因此在我看来,esbuild 激发人们对于让开发工具更快的广泛兴趣。Evan 选择了使用 Go:

Rust版本也许可以通过足够的努力使其以同等速度工作。但在高层次上,Go 的工作方式更令人愉快。这是一个 side project ,所以它对我来说必须要有乐趣。

—— Evan,Creator of esbuild( Source[29] )

有人认为 Rust 可以表现得更好,但两者都可以实现 Evan 最初的目标,即影响社区:

即使只是进行了基本的优化,Rust也能够胜过超手工调整的 Go 版本。这是一个巨大的证明,与我们不得不对 Go 的深入研究相比,用Rust编写高效程序是多么容易。

—— Discord[30]

Rome

Rome[31] 创建于 2020 年 8 月,包含 linter、compiler、bundler、test runner 以及其它东西,适用于 JavaScript、TypeScript、HTML、JSON、Markdown 和 CSS 。他们的目标是取代和统一整个前端开发工具链。它是由 Sebastian[32] 创建的,他是 Babel 的创建者。

那么,为什么要重写一切呢?

对 Babel 进行必要的修改,使其成为其他工具的可靠基础,这绝对需要对所有东西进行修改。这个架构与我在 2014 年学习解析器、 AST 和编译器时做出的最初设计选择是有紧密联系的。

—— Sebastian( Source[33] )

Rome 目前是用 TypeScript 编写的,在 Node.js 上运行。但他们现在正致力于 用 Rust[34] 重写[35] 。

NAPI

Rust 与 Node.js 的整合比其他低级语言更好。

napi-rs[36] 允许你用 Rust 构建预编译的 Node.js add-ons 。它为交叉编译(cross-compilation)和向 NPM 发布本地二进制文件提供了一个开箱即用的解决方案,不需要 node-gyp 或使用 postinstall 。

相应的,你也能轻松构建一个被 Node.js 侧直接调用的 Rust 模块,而不需要像 esbuild 那样创建一个子进程。

Rust + WebAssembly

WebAssembly[37] (WASM)是一种可移植的低级语言,Rust 可以编译成它。它在浏览器中运行,可与 JavaScript 互操作,并被所有主要的现代浏览器所支持。

WASM 肯定比 JS 快很多,但还没有达到原生速度。在我们的测试中,Parcel 编译成 WASM 后的运行速度比使用本地二进制文件慢 10 - 20 倍。

—— Devon Govett[38]

虽然 WASM 还不是完美的解决方案,但它可以帮助开发者创建极快的 Web 体验。Rust 团队 致力于[39] 实现高质量和先进(cutting edge)的 WASM 实现。对于开发者来说,这意味着你可以拥有 Rust 的性能优势(相对于 Go ),同时还可以为 Web 服务(使用 WASM )。

这个领域的一些早期库和框架:

  • Yew[40]

  • Percy[41]

  • Seed[42]

  • Sycamore[43]

  • Stork[44]

这些基于 Rust 的、可编译为 WASM 的 Web 框架并不是要取代 JavaScript,而是要与之一起工作。虽然我们还没有达到这个目的,但看到 Rust 在两方面都追随 Web 的发展是很有趣的:使现有的 JavaScript 工具更快,并在未来提出 编译到 WASM[45] 的想法。

这就是 Rust 之后的路。

为什么不选择 Rust ?

Rust 有一个陡峭的学习曲线。它的抽象程度比大多数 Web 开发者所习惯的要低。

Rust 会迫使你思考你代码中对系统编程方面具有很大影响的部分。它让你思考内存是如何共享或复制的。它让你思考真实但不可能发生的边界问题,并确保它们得到处理。它可以帮助你写出在所有可能的方面都非常高效的代码。

—— Tom MacWright ( Source[46] )

此外,Rust 在网络社区的使用仍然是小众的。它还没有达到技术选型临界点(critical adoption)。即使学习 Rust 的 JavaScript 工具会有一定的门槛,但有趣的是,开发者宁愿拥有一个 更快、更难参与贡献[47] 的工具。唯快不破[48](Fast software wins)[49] 。

目前,你很难为你喜欢的服务(如登录鉴权、数据库、支付等工作)找到一个 Rust 库或框架。我确实认为,一旦 Rust 和 WASM 达到技术选型临界点(critical adoption),这个问题会自行解决。但现在还不行。我们需要现有的 JavaScript 工具来帮助我们缩小差距,并逐步采用性能改进。

JavaScript 工具化的未来

我相信 Rust 是 JavaScript 工具化的未来。Next.js 12[50] 已经开始了我们的转型,用 SWC 和 Rust 完全取代 Babel(transpilation)和 Terser(压缩)。为什么会有这样的选择?

  • 可扩展性(Extensibility) 。SWC 可以作为 Next.js 内部的一个 Crate 使用,而无需 fork 其它库或面临设计上的限制(workaround design constraints)。

  • 性能(Performance) 。通过改用 SWC ,我们在 Next.js 中实现了约 3 倍的刷新速度(Fast Refresh)和约 5 倍的构建速度,还有更多的优化正在进行。

  • WebAssembly 。Rust 对 WASM 的支持,使得 Next.js 可以支持所有可能的平台,让 Next.js 遍布所有的地方。

  • 社区(Community) 。Rust 社区和生态系统是惊人的,而且还在不断增长。

在逐步使用 SWC 的绝不仅仅是 Next.js:

  • Deno[51] linter、代码格式化器和文档生成器都是用 SWC 构建的[52] 。

  • Rome[53] 正在 用 Rust 重写[54] ,并计划使用 SWC 。

  • dprint[55] ,建立在 SWC 之上,一个快 30 倍的用于替代 Prettier 的代码格式化工具。

  • Parcel[56] 使用 SWC 将整体构建性能 提高了 10 倍[57] 。

Parcel 像一个库一样使用 SWC 。之前我们使用 Babel 的解析器和用 JS 编写的自定义转换。现在,我们使用 SWC 的解析器和 Rust 中的 自定义转换[58] 。这包括一个全局 hoisting 的实现、依赖性收集等。它的范围类似于 Deno 在 SWC 之上的构建方式。

—— Devon Govett[59]

现在是 Rust 的早期阶段 —— 有几个重要的部分还在摸索之中:

  • 插件(Plungins) 。对于许多 JavaScript 开发者来说,用 Rust 编写插件并不是那么容易的。同时,在 JavaScript 中暴露一个插件系统可能会否定性能的提升。目前还没有一个明确的解决方案。

  • 打包(Bundling) 。一个有趣的发展领域是 swcpack ,它是 SWC 对 Webpack 的替代。它仍在开发中,但可能是非常有前途的。

  • WebAssembly 。如上所述,编写 Rust 并编译成 WASM 的前景很诱人,但仍有工作要做。

不管怎么说,我相信 Rust 会在未来 1 - 2 年以及未来继续对 JavaScript 生态系统产生重大影响。想象一下这样一个世界:Next.js 中使用的所有构建工具都是用 Rust 编写的,给你带来最佳性能。然后,Next.js 可以作为一个 静态二进制文件[60] (static binary)分发,你可以从 NPM 下载。

这就是我想生活(和建设)的世界。

感谢Devon Govett[61] 审阅本文的早期草稿。

参考资料

[1]

Rust Is The Future of JavaScript Infrastructure – Lee Robinson: https://leerob.io/blog/rust

[2]

Rust: https://www.rust-lang.org/

[3]

欢: https://insights.stackoverflow.com/survey/2016#technology-most-loved-dreaded-and-wanted

[4]

迎: https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted

[5]

编: https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages

[6]

程: https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages

[7]

语: https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages

[8]

言: https://insights.stackoverflow.com/survey/2020#most-loved-dreaded-and-wanted

[9]

Facebook: https://engineering.fb.com/2021/04/29/developer-tools/rust/

[10]

苹果: https://twitter.com/oskargroth/status/1301502690409709568

[11]

亚马逊: https://aws.amazon.com/blogs/opensource/why-aws-loves-rust-and-how-wed-like-to-help/

[12]

微软: https://twitter.com/ryan_levick/status/1171830191804551168

[13]

谷歌: https://security.googleblog.com/2021/04/rust-in-android-platform.html

[14]

垃圾回收: https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

[15]

—— Discord: https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f

[16]

Firecracker: https://github.com/firecracker-microvm/firecracker

[17]

Bottlerocket: https://github.com/bottlerocket-os/bottlerocket

[18]

Quiche: https://github.com/cloudflare/quiche

[19]

Neqo: https://github.com/mozilla/neqo

[20]

—— Dropbox: https://dropbox.tech/infrastructure/rewriting-the-heart-of-our-sync-engine

[21]

SWC: http://swc.rs/

[22]

Deno: https://deno.land/

[23]

V8: https://v8.dev/

[24]

5月才达到: https://deno.com/blog/v1

[25]

v1.0: https://deno.com/blog/v1

[26]

SWC 构建的: https://twitter.com/devongovett/status/1369033422002389000

[27]

esbuild: https://esbuild.github.io/

[28]

Source: https://news.ycombinator.com/item?id=22336334

[29]

Source: https://news.ycombinator.com/item?id=22336284

[30]

—— Discord: https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f

[31]

Rome: https://rome.tools/blog/2020/08/08/introducing-rome

[32]

Sebastian: https://twitter.com/sebmck

[33]

Source: https://rome.tools/blog/2020/08/08/introducing-rome

[34]

用 Rust: https://twitter.com/rometools/status/1422616144763097091

[35]

重写: https://twitter.com/rometools/status/1422616144763097091

[36]

napi-rs: https://napi.rs/

[37]

WebAssembly: https://webassembly.org/docs/use-cases/

[38]

Devon Govett: https://twitter.com/devongovett

[39]

致力于: https://www.rust-lang.org/what/wasm

[40]

Yew: https://yew.rs/

[41]

Percy: https://github.com/chinedufn/percy

[42]

Seed: https://github.com/seed-rs/seed

[43]

Sycamore: https://github.com/sycamore-rs/sycamore

[44]

Stork: https://stork-search.net/

[45]

编译到 WASM: https://rustwasm.github.io/docs/book/introduction.html

[46]

Source: https://macwright.com/2021/01/15/rust.html

[47]

更快、更难参与贡献: https://twitter.com/devongovett/status/1261379312898306048

[48]

唯快不破: https://craigmod.com/essays/fast_software/

[49]

Fast software wins): https://craigmod.com/essays/fast_software/

[50]

Next.js 12: http://nextjs.org/12

[51]

Deno: https://deno.land/

[52]

SWC 构建的: https://twitter.com/devongovett/status/1369033422002389000

[53]

Rome: https://rome.tools/

[54]

用 Rust 重写: https://twitter.com/rometools/status/1422616144763097091

[55]

dprint: https://github.com/devongovett/dprint-node

[56]

Parcel: https://parceljs.org/

[57]

提高了 10 倍: https://v2.parceljs.org/blog/beta3/

[58]

自定义转换: https://github.com/parcel-bundler/parcel/tree/v2/packages/transformers/js/core/src

[59]

Devon Govett: https://twitter.com/devongovett

[60]

静态二进制文件: https://en.wikipedia.org/wiki/Static_build

[61]

Devon Govett: https://twitter.com/devongovett


- EOF -

推荐阅读  点击标题可跳转

1、使用 Rust 编写更快的 React 组件

2、对话Svelte未来,Rust 编译器?构建大型应用?

3、这几个 JavaScript 断点调试技能你有必要掌握!


觉得本文对你有帮助?请分享给更多人

推荐关注「前端大全」,提升前端技能

点赞和在看就是最大的支持❤️

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存