Rust 是 JavaScript 基礎設施的未來

本文翻譯自: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 還被用於流行的開源庫,比如:

Rust 一直是我們團隊的力量源泉,押注 Rust 是我們做出的最好決定之一。除了性能之外,它的人機工程學( ergonomics )和對正確性的關注也幫助我們控制了同步的複雜性。我們可以在類型系統中對系統的複雜不變性進行編碼,讓編譯器爲我們檢查。

—— Dropbox[20]

從 JavaScript 到 Rust

JavaScript 是使用最廣泛的編程語言,存在於每個有瀏覽器的設備上。在過去的十年中,圍繞着 JavaScript 已經建立了一個龐大的生態系統:

數以百萬計的代碼被編寫出來,甚至更多的 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 )。

這個領域的一些早期庫和框架:

這些基於 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(壓縮)。爲什麼會有這樣的選擇?

在逐步使用 SWC 的絕不僅僅是 Next.js:

Parcel 像一個庫一樣使用 SWC 。之前我們使用 Babel 的解析器和用 JS 編寫的自定義轉換。現在,我們使用 SWC 的解析器和 Rust 中的 自定義轉換 [58] 。這包括一個全局 hoisting 的實現、依賴性收集等。它的範圍類似於 Deno 在 SWC 之上的構建方式。

—— Devon Govett[59]

現在是 Rust 的早期階段 —— 有幾個重要的部分還在摸索之中:

不管怎麼說,我相信 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

[62]

https://live.juejin.cn/4354/rescript-lang: https://live.juejin.cn/4354/rescript-lang

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/QJep1c5VRr-Gxj7TqKyHqA