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 還被用於流行的開源庫,比如:
-
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
[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