Dan:Rust 是 JavaScript 基礎設施的未來
本文翻譯自:Rust Is The Future of JavaScript Infrastructure – Lee Robinson[1] ,已獲得作者授權,原文略做修改以符合中文語境。

(圖片鎮(zhèn)樓,與原文無關)
Rust[2] 是一種快速、可靠、內(nèi)存高效的編程語言。它已經(jīng)連續(xù)六年被評為最受 歡[3] 迎[4] 的 編[5] 程[6] 語[7] 言[8] 。它由 Mozilla 創(chuàng)建,現(xiàn)在被 Facebook[9] 、 蘋果[10] 、 亞馬遜[11] 、 微軟[12] 和 谷歌[13] 用于系統(tǒng)基礎設施、加密、虛擬化和更多底層(low-level)的編程中。
為什么Rust現(xiàn)在被用來取代 JavaScript 成為 Web 生態(tài)系統(tǒng)的一部分,如壓縮(Terser)、編譯(Babel)、格式化(Prettier)、打包(webpack)、linting(ESLint),以及其他場景?
什么是Rust?
Rust 幫助開發(fā)人員編寫運行快并高效利用內(nèi)存的軟件。它是 C++ 或 C 等語言的現(xiàn)代替代品,聚焦在代碼安全和簡潔的語法。
Rust 與 JavaScript 有很大不同。JavaScript 采用的是 垃圾回收[14] 機制,會試圖清除不再使用的變量和對象。JavaScript 將開發(fā)者從對手動內(nèi)存管理的思考中抽離出來。
有了 Rust,開發(fā)者對內(nèi)存分配有了更多的控制,而不像 C++ 或 Go 那樣令人痛苦。
Rust 使用了一種相對獨特的內(nèi)存管理方法,包含了內(nèi)存“所有權”的概念。基本上,Rust 會記錄誰可以讀取和寫入內(nèi)存。它知道程序什么時候在使用內(nèi)存,一旦不再需要就立即釋放內(nèi)存。它在編譯時執(zhí)行內(nèi)存規(guī)則,使得運行時的內(nèi)存錯誤幾乎不可能出現(xiàn)。你不需要手動跟蹤內(nèi)存。編譯器會照顧到這一點。
—— Discord[15]
Adoption
在上面提到的公司之外,Rust 還被用于流行的開源庫,比如:
Firecracker[16] (AWS)
Bottlerocket[17] (AWS)
Quiche[18] (Cloudflare)
Neqo[19] (Mozilla)
Rust 一直是我們團隊的力量源泉,押注Rust是我們做出的最好決定之一。除了性能之外,它的人機工程學( ergonomics )和對正確性的關注也幫助我們控制了同步的復雜性。我們可以在類型系統(tǒng)中對系統(tǒng)的復雜不變性進行編碼,讓編譯器為我們檢查。
—— Dropbox[20]
從 JavaScript 到 Rust
JavaScript 是使用最廣泛的編程語言,存在于每個有瀏覽器的設備上。在過去的十年中,圍繞著 JavaScript 已經(jīng)建立了一個龐大的生態(tài)系統(tǒng):
Webpack :開發(fā)者希望將多個 JavaScript 文件 bundle 成一個文件。
Babel :開發(fā)者希望在支持舊版瀏覽器的同時編寫現(xiàn)代 JavaScript 。
Terser :開發(fā)者希望生成盡可能小的文件。
Prettier :開發(fā)者希望有一個有自帶規(guī)則(opinionated)的代碼格式化器,剛好可用就行。
ESLint :開發(fā)者希望在部署前發(fā)現(xiàn)他們的代碼存在的問題。
數(shù)以百萬計的代碼被編寫出來,甚至更多的 bug 被修復,從而為今天的 Web 應用提供了基礎。所有這些工具都是用 JavaScript 或 TypeScript 編寫的。目前已經(jīng)做的很不錯了,但我們對 JS 的優(yōu)化已經(jīng)達到頂峰。因此,這激發(fā)了一類新的工具們的誕生,旨在極大地提高 Web 構建的性能。
SWC
SWC[21] 創(chuàng)建于 2017 年,一個下一代快速開發(fā)的工具,是一個基于 Rust 的可擴展平臺。Next.js、 Parcel 和 Deno 等工具,以及 Vercel、字節(jié)跳動、騰訊、Shopify 等公司都在使用它。
SWC 可用于編譯(compilation)、壓縮(minification)、打包(bundling)等 —— 并且被設計成可擴展的。你可以調(diào)用它來執(zhí)行代碼轉換(無論是內(nèi)置的還是自定義的)。這些轉換由更高維度的工具來運行,比如 Next.js 。
Deno
Deno[22] 創(chuàng)建于 2018 年,是一個簡單、現(xiàn)代、安全的 JavaScript 和 TypeScript 的運行時,Deno 使用 V8[23] 的同時,并以 Rust 構建。它試圖取代 Node.js ,由 Node.js 的原作者創(chuàng)建。雖然它是在 2018 年創(chuàng)建的,但直到 2020 年 5月才達到[24] v1.0[25] 。
Deno 的 linter、code formatter 和文檔生成器是使用 SWC 構建的[26] 。
esbuild
esbuild[27] 創(chuàng)建于 2020 年 1 月,一個代碼打包和壓縮的工具,它是用 Go 寫的,比當今的工具快 10 到 100 倍。
我試圖創(chuàng)建一個構建工具:
A)能夠在一個合理的場景(bundler JavaScript,TypeScript,也許還有CSS)中工作得很好。
B)能夠重新定義社區(qū)對構建工具速度的期望。對于JS快速構建工具來說,到底什么才是快?在我看來,我們目前的工具都太慢了。
—— Evan,Creator of esbuild( Source[28] )
在 esbuild 發(fā)布之前,用系統(tǒng)編程語言(如 Go 和 Rust )構建 JavaScript 工具是相當小眾的。因此在我看來,esbuild 激發(fā)人們對于讓開發(fā)工具更快的廣泛興趣。Evan 選擇了使用 Go:
Rust版本也許可以通過足夠的努力使其以同等速度工作。但在高層次上,Go 的工作方式更令人愉快。這是一個 side project ,所以它對我來說必須要有樂趣。
—— Evan,Creator of esbuild( Source[29] )
有人認為 Rust 可以表現(xiàn)得更好,但兩者都可以實現(xiàn) Evan 最初的目標,即影響社區(qū):
即使只是進行了基本的優(yōu)化,Rust也能夠勝過超手工調(diào)整的 Go 版本。這是一個巨大的證明,與我們不得不對 Go 的深入研究相比,用Rust編寫高效程序是多么容易。
—— Discord[30]
Rome
Rome[31] 創(chuàng)建于 2020 年 8 月,包含 linter、compiler、bundler、test runner 以及其它東西,適用于 JavaScript、TypeScript、HTML、JSON、Markdown 和 CSS 。他們的目標是取代和統(tǒng)一整個前端開發(fā)工具鏈。它是由 Sebastian[32] 創(chuàng)建的,他是 Babel 的創(chuàng)建者。
那么,為什么要重寫一切呢?
對 Babel 進行必要的修改,使其成為其他工具的可靠基礎,這絕對需要對所有東西進行修改。這個架構與我在 2014 年學習解析器、 AST 和編譯器時做出的最初設計選擇是有緊密聯(lián)系的。
—— Sebastian( Source[33] )
Rome 目前是用 TypeScript 編寫的,在 Node.js 上運行。但他們現(xiàn)在正致力于 用 Rust[34] 重寫[35] 。
NAPI
Rust 與 Node.js 的整合比其他低級語言更好。
napi-rs[36] 允許你用 Rust 構建預編譯的 Node.js add-ons 。它為交叉編譯(cross-compilation)和向 NPM 發(fā)布本地二進制文件提供了一個開箱即用的解決方案,不需要 node-gyp 或使用 postinstall 。
相應的,你也能輕松構建一個被 Node.js 側直接調(diào)用的 Rust 模塊,而不需要像 esbuild 那樣創(chuàng)建一個子進程。
Rust + WebAssembly
WebAssembly[37] (WASM)是一種可移植的低級語言,Rust 可以編譯成它。它在瀏覽器中運行,可與 JavaScript 互操作,并被所有主要的現(xiàn)代瀏覽器所支持。
WASM 肯定比 JS 快很多,但還沒有達到原生速度。在我們的測試中,Parcel 編譯成 WASM 后的運行速度比使用本地二進制文件慢 10 - 20 倍。
—— Devon Govett[38]
雖然 WASM 還不是完美的解決方案,但它可以幫助開發(fā)者創(chuàng)建極快的 Web 體驗。Rust 團隊 致力于[39] 實現(xiàn)高質(zhì)量和先進(cutting edge)的 WASM 實現(xiàn)。對于開發(fā)者來說,這意味著你可以擁有 Rust 的性能優(yōu)勢(相對于 Go ),同時還可以為 Web 服務(使用 WASM )。
這個領域的一些早期庫和框架:
Yew[40]
Percy[41]
Seed[42]
Sycamore[43]
Stork[44]
這些基于 Rust 的、可編譯為 WASM 的 Web 框架并不是要取代 JavaScript,而是要與之一起工作。雖然我們還沒有達到這個目的,但看到 Rust 在兩方面都追隨 Web 的發(fā)展是很有趣的:使現(xiàn)有的 JavaScript 工具更快,并在未來提出 編譯到 WASM[45] 的想法。
這就是 Rust 之后的路。
為什么不選擇 Rust ?
Rust 有一個陡峭的學習曲線。它的抽象程度比大多數(shù) Web 開發(fā)者所習慣的要低。
Rust 會迫使你思考你代碼中對系統(tǒng)編程方面具有很大影響的部分。它讓你思考內(nèi)存是如何共享或復制的。它讓你思考真實但不可能發(fā)生的邊界問題,并確保它們得到處理。它可以幫助你寫出在所有可能的方面都非常高效的代碼。
—— Tom MacWright ( Source[46] )
此外,Rust 在網(wǎng)絡社區(qū)的使用仍然是小眾的。它還沒有達到技術選型臨界點(critical adoption)。即使學習 Rust 的 JavaScript 工具會有一定的門檻,但有趣的是,開發(fā)者寧愿擁有一個 更快、更難參與貢獻[47] 的工具。唯快不破[48](Fast software wins)[49] 。
目前,你很難為你喜歡的服務(如登錄鑒權、數(shù)據(jù)庫、支付等工作)找到一個 Rust 庫或框架。我確實認為,一旦 Rust 和 WASM 達到技術選型臨界點(critical adoption),這個問題會自行解決。但現(xiàn)在還不行。我們需要現(xiàn)有的 JavaScript 工具來幫助我們縮小差距,并逐步采用性能改進。
JavaScript 工具化的未來
我相信 Rust 是 JavaScript 工具化的未來。Next.js 12[50] 已經(jīng)開始了我們的轉型,用 SWC 和 Rust 完全取代 Babel(transpilation)和 Terser(壓縮)。為什么會有這樣的選擇?
可擴展性(Extensibility) 。SWC 可以作為 Next.js 內(nèi)部的一個 Crate 使用,而無需 fork 其它庫或面臨設計上的限制(workaround design constraints)。
性能(Performance) 。通過改用 SWC ,我們在 Next.js 中實現(xiàn)了約 3 倍的刷新速度(Fast Refresh)和約 5 倍的構建速度,還有更多的優(yōu)化正在進行。
WebAssembly 。Rust 對 WASM 的支持,使得 Next.js 可以支持所有可能的平臺,讓 Next.js 遍布所有的地方。
社區(qū)(Community) 。Rust 社區(qū)和生態(tài)系統(tǒng)是驚人的,而且還在不斷增長。
在逐步使用 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 編寫的自定義轉換?,F(xiàn)在,我們使用 SWC 的解析器和 Rust 中的 自定義轉換[58] 。這包括一個全局 hoisting 的實現(xiàn)、依賴性收集等。它的范圍類似于 Deno 在 SWC 之上的構建方式。
—— Devon Govett[59]
現(xiàn)在是 Rust 的早期階段 —— 有幾個重要的部分還在摸索之中:
插件(Plungins) 。對于許多 JavaScript 開發(fā)者來說,用 Rust 編寫插件并不是那么容易的。同時,在 JavaScript 中暴露一個插件系統(tǒng)可能會否定性能的提升。目前還沒有一個明確的解決方案。
打包(Bundling) 。一個有趣的發(fā)展領域是 swcpack ,它是 SWC 對 Webpack 的替代。它仍在開發(fā)中,但可能是非常有前途的。
WebAssembly 。如上所述,編寫 Rust 并編譯成 WASM 的前景很誘人,但仍有工作要做。
不管怎么說,我相信 Rust 會在未來 1 - 2 年以及未來繼續(xù)對 JavaScript 生態(tài)系統(tǒng)產(chǎn)生重大影響。想象一下這樣一個世界:Next.js 中使用的所有構建工具都是用 Rust 編寫的,給你帶來最佳性能。然后,Next.js 可以作為一個 靜態(tài)二進制文件[60] (static binary)分發(fā),你可以從 NPM 下載。
這就是我想生活(和建設)的世界。
感謝Devon Govett[61] 審閱本文的早期草稿。
全文完
活動推薦:
一個是前 Facebook 程序員,一個是在中國遠程的現(xiàn)Facebook程序員,兩位都研究過開發(fā)編程語言,兩位都是在開發(fā)領域有所建樹的程序員大佬,趙海平 與 張宏波與你聊聊以往經(jīng)歷,聊聊職業(yè)發(fā)展,聊聊編程語言~ 11月16號 (周二), 17:00 - 19:00,掘金直播間,海平和宏波與你不見不散~
直播地址??:https://live.juejin.cn/4354/rescript-lang[62]
?? 掃碼回復 “編程語言”,入群交流
參考資料
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]靜態(tài)二進制文件: 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
