Rust 會成為 JavaScript 基礎(chǔ)設(shè)施的未來嗎?
Rust 最初由 Mozilla 創(chuàng)建,是一種快速、可靠、內(nèi)存效率高且非常流行的編程語言,專為提高性能和安全性而設(shè)計(jì)。它連續(xù) 6 年被 Stack Overflow 調(diào)查評為最喜愛的編程語言,并在超大規(guī)模的公司使用,如 Facebook,蘋果,亞馬遜,微軟和谷歌等用于系統(tǒng)基礎(chǔ)設(shè)施、加密和虛擬化。Rust 現(xiàn)在正在取代 JavaScript Web 生態(tài)系統(tǒng)的部分內(nèi)容,例如壓縮 (Terser)、轉(zhuǎn)譯 (Babel)、格式化 (Prettier)、打包 (webpack)、linting (ESLint) 等等。讓我們深入探討一下為什么這種趨勢越來越受歡迎和被廣泛采用。
1、Rust 是什么?
Rust 幫助開發(fā)人員編寫內(nèi)存高效的快速軟件。它是 C++ 或 C 等語言的現(xiàn)代替代品,專注于代碼安全和簡潔的語法。Rust 與 JavaScript 完全不同。JavaScript 嘗試查找未使用的變量或?qū)ο蟛⒆詣訌膬?nèi)存中清除它們。這稱為垃圾收集。該語言將開發(fā)人員從手動內(nèi)存管理的思考中抽象出來。使用 Rust,開發(fā)人員可以更好地控制內(nèi)存分配,而不會像 C++ 那樣痛苦。
“Rust 使用了一種相對獨(dú)特的內(nèi)存管理方法,它結(jié)合了內(nèi)存‘所有權(quán)’的概念。Rust 會跟蹤誰可以讀寫內(nèi)存。它知道程序何時(shí)使用內(nèi)存,并在不再需要時(shí)立即釋放內(nèi)存。它在編譯時(shí)強(qiáng)制執(zhí)行內(nèi)存規(guī)則,幾乎不可能出現(xiàn)運(yùn)行時(shí)內(nèi)存錯誤。你不需要手動跟蹤內(nèi)存。編譯器會處理它。” — Discord [1]
2、Rust 使用情況
除了上述公司之外,Rust 還被用于流行的開源庫,例如:
-
Firecracker [2] (AWS)
-
Bottlerocket [3] (AWS)
-
Quiche [4] (Cloudflare)
-
Neqo [5] (Mozilla)
“Rust 一直是我們團(tuán)隊(duì)的力量倍增器,押注 Rust 是我們做出的最佳決定之一。不僅僅是性能,它的人體工程學(xué)和對正確性的關(guān)注幫助我們馴服了同步的復(fù)雜性。我們可以在類型系統(tǒng)中編碼關(guān)于我們系統(tǒng)的復(fù)雜不變量,并讓編譯器為我們檢查它們。” — Dropbox [6]
3、從 JavaScript 到 Rust
JavaScript 是使用最廣泛的編程語言,可在每個帶有網(wǎng)絡(luò)瀏覽器的設(shè)備上運(yùn)行。在過去的 10 年里,圍繞 JavaScript 構(gòu)建了一個龐大的生態(tài)系統(tǒng):
-
Webpack:開發(fā)人員希望將多個 JavaScript 文件捆綁為一個。
-
Babel:開發(fā)人員希望在支持舊瀏覽器的同時(shí)編寫現(xiàn)代 JavaScript。
-
Terser:開發(fā)人員希望生成盡可能小的文件。
-
Prettier:開發(fā)人員想要一個可以正常工作的固執(zhí)己見的代碼格式化程序。
-
ESLint:開發(fā)人員希望在部署之前發(fā)現(xiàn)他們的代碼存在的問題。
已經(jīng)編寫了數(shù)百萬行代碼,并且修復(fù)了更多 bug,為當(dāng)今的 Web 應(yīng)用程序提供了基礎(chǔ)。所有這些工具都是用 JavaScript 或 TypeScript 編寫的。它們工作得很好,但我們已經(jīng)達(dá)到了 JS 的最佳優(yōu)化。這激發(fā)了一類新的工具,這些工具旨在大幅提高 Web 構(gòu)建的性能。
SWC
SWC [7] 創(chuàng)建于 2017 年,是一個基于 Rust 的可擴(kuò)展平臺,適用于下一代快速開發(fā)工具。它被 Next.js、Parcel 和 Deno 等工具以及 Vercel、字節(jié)跳動、騰訊、Shopify 等公司使用。SWC 可用于編譯、縮小、打包等 - 并且旨在進(jìn)行擴(kuò)展。你可以調(diào)用它來執(zhí)行代碼轉(zhuǎn)換(內(nèi)置或自定義)。通過 Next.js 等更高級別的工具運(yùn)行這些轉(zhuǎn)換。
Deno
Deno [8] 創(chuàng)建于 2018 年,是一個簡單、現(xiàn)代且安全的 JavaScript 和 TypeScript 運(yùn)行時(shí),它基于 V8 [9] 并使用 Rust 構(gòu)建。它試圖取代由 Node.js 的原始創(chuàng)建者編寫的 Node.js。雖然它是在 2018 年創(chuàng)建的,但直到 2020 年 5 月才發(fā)布 v1.0 [10] 。Deno 的 linter、代碼格式化程序和文檔生成器是 使用 SWC 構(gòu)建的 [11] 。
esbuild
esbuild [12] 創(chuàng)建于 2020 年 1 月,是一個 JavaScript 打包器和壓縮器,比用 Go 編寫的其他工具快 10-100 倍。
“我正在嘗試創(chuàng)建一個構(gòu)建工具,它 a) 適用于給定的最佳用例(打包 JavaScript、TypeScript,也許還有 CSS),b) 重塑社區(qū)對 JavaScript 構(gòu)建意味著工具要快。在我看來,我們目前的工具太慢了。” — Evan [13] ,esbuild 的創(chuàng)建者
在 esbuild 發(fā)布之前,使用 Go 和 Rust 等系統(tǒng)編程語言構(gòu)建 JavaScript 工具是相當(dāng)小眾的。在我看來,esbuild 激發(fā)了人們更廣泛的興趣,試圖讓開發(fā)者工具變得更快。Evan 選擇使用 Go:
“只要付出足夠的努力,Rust 版本能以相同的速度運(yùn)行。但在高層次上,Go 的工作要愉快得多。這是一個附帶項(xiàng)目,對我來說工作起來一定很有趣。” — Evan,esbuild 的創(chuàng)建者
有人認(rèn)為 Rust 可以表現(xiàn)得更好,但兩者都可以實(shí)現(xiàn) Evan 影響社區(qū)的最初目標(biāo):
“即使只有基本的優(yōu)化,Rust 也能勝過超級手動調(diào)整的 Go 版本。與我們必須使用 Go 進(jìn)行的深入研究相比,這極大地證明了使用 Rust 編寫高效的程序是多么容易。” —Discord
Rome
Rome [14] 于 2020 年 8 月創(chuàng)建,是一個用于 JavaScript、TypeScript、HTML、JSON、Markdown 和 CSS 的 linter、編譯器、捆綁器、測試運(yùn)行器等。他們的目標(biāo)是替換和統(tǒng)一整個前端開發(fā)工具鏈。它是由 Sebastian McKenzie [15] 創(chuàng)建的,他之前還創(chuàng)建了 Babel。
那為什么要重寫一個呢?
“對 Babel 進(jìn)行必要的修改以使其成為其他工具的可靠基礎(chǔ)將需要對所有內(nèi)容進(jìn)行更改。該架構(gòu)與我在 2014 年學(xué)習(xí)解析器、AST 和編譯器時(shí)所做的初始設(shè)計(jì)選擇有關(guān)。” — Sebastian McKenzie [16]
Rome 目前使用 TypeScript 編寫并在 Node.js 上運(yùn)行。但是他們現(xiàn)在正在使用 RSLint 解析器和他們自己的訪問者系統(tǒng)來 用 Rust 重寫 [17] 以進(jìn)行 AST 遍歷。
NAPI
Rust 與 Node.js 的集成優(yōu)于其他低級語言。 napi-rs [18] 允許你使用 Rust 構(gòu)建預(yù)編譯的 Node.js 插件。它提供了交叉編譯和發(fā)布本地的二進(jìn)制文件 NPM:一個徹頭徹尾的現(xiàn)成的解決方案,而無需 node-gyp
或 postinstall
腳本。你可以構(gòu)建一個可以直接從 Node.js 調(diào)用的 Rust 模塊,而無需創(chuàng)建像 esbuild 這樣的子進(jìn)程。
Rust + WebAssembly
WebAssembly [19] (WASM) 是 Rust 可以編譯成的一種可移植的低級語言。它在瀏覽器中運(yùn)行,可與 JavaScript 互操作,并在所有主要的現(xiàn)代瀏覽器中均受支持。
“WASM 肯定比 JS 快很多,但不如原生速度。在我們的測試中,Parcel 編譯為 WASM 時(shí)的運(yùn)行速度比使用原生二進(jìn)制文件慢 10-20 倍。” — Devon Govett
雖然 WASM 還不是完美的解決方案,但它可以幫助開發(fā)人員創(chuàng)建極快的 Web 體驗(yàn)。Rust 團(tuán)隊(duì) 致力于 [20] 高質(zhì)量和尖端的 WASM 實(shí)現(xiàn)。對于開發(fā)人員來說,這意味著你可以擁有 Rust(相對于 Go)的性能優(yōu)勢,同時(shí)仍然為 Web 編譯(使用 WASM)。
該領(lǐng)域的一些早期庫和框架:
-
Yew [21]
-
Percy [22]
-
Seed [23]
-
Sycamore [24]
-
Stork [25]
這些編譯為 WASM 的基于 Rust 的 Web 框架并沒有試圖取代 JavaScript,而是與它一起工作。雖然我們還沒有到那一步,但有趣的是看到 Rust 在兩個方面都在 Web 之后出現(xiàn):使現(xiàn)有的 JavaScript 工具更快,并為 編譯為 WASM 提供 [26] 未來的想法。從頭到尾都是 Rust。
4、Rust 有什么問題?
Rust 學(xué)習(xí)曲線陡峭,網(wǎng)友戲稱:Rust 入門很容易,我已經(jīng)入門 4、5 次了。它的抽象級別比大多數(shù) Web 開發(fā)人員習(xí)慣的要低。一旦你使用本機(jī)代碼(通過 Rust、Go、Zig 或其他低級語言),算法和數(shù)據(jù)結(jié)構(gòu)比語言選擇 更重要 [27] 。這不是銀彈。
“Rust 讓你思考對系統(tǒng)編程非常重要的代碼維度。它讓你思考如何共享或復(fù)制內(nèi)存。它使你考慮真實(shí)但不太可能的極端情況,并確保它們得到處理。它可以幫助你以各種可能的方式編寫極其高效的代碼。” — Tom MacWright [28]
此外,Rust 在網(wǎng)絡(luò)社區(qū)中的使用仍然是小眾的。它還沒有達(dá)到關(guān)鍵的使用量。盡管為 JavaScript 工具學(xué)習(xí) Rust 將成為入門障礙,但有趣的是,開發(fā)人員更愿意擁有一個更快的工具,即使為其貢獻(xiàn)代碼挺難。
目前,很難為NIIT喜歡的服務(wù)(例如使用身份驗(yàn)證、數(shù)據(jù)庫、支付等)找到一個 Rust 庫或框架。我認(rèn)為一旦 Rust 和 WASM 獲得關(guān)鍵采用,這將自行解決。但目前還不成熟。我們需要現(xiàn)有的 JavaScript 工具來幫助我們彌合差距并逐步采用以改進(jìn)性能。
5、JavaScript 工具的未來
我相信 Rust 是 JavaScript 工具的未來。 Next.js 12 [29] 開始了我們的過渡,用 SWC 和 Rust 完全替換 Babel(轉(zhuǎn)譯)和 Terser(壓縮)。為什么?
-
可擴(kuò)展性:SWC 可以用作 Next.js 中的 Crate,而無需 fork 庫或解決設(shè)計(jì)約束。
-
性能:通過切換到 SWC,我們能夠在 Next.js 中實(shí)現(xiàn)約 3 倍的快速刷新和約 5 倍的構(gòu)建速度,還有更多的優(yōu)化空間仍在進(jìn)行中。
-
WebAssembly:Rust 對 WASM 的支持對于支持所有可能的平臺和在任何地方進(jìn)行 Next.js 開發(fā)至關(guān)重要。
-
社區(qū):Rust 社區(qū)和生態(tài)系統(tǒng)令人驚嘆,而且還在不斷增長。
不僅僅是 Next.js 采用了 SWC:
-
Deno [30] 的 linter、代碼格式化程序和文檔生成器是 使用 SWC 構(gòu)建的 [31] 。
-
dprint [32] 建立在 SWC 之上,是 Prettier [33] 的 30 倍 [34] 代碼格式化替代品。
-
Parcel [35] 使用 SWC 將整體構(gòu)建性能提高了 10 倍 [36] 。
“在我們使用 Babel 的解析器和用 JS 編寫的自定義轉(zhuǎn)換之前,Parcel 像庫一樣使用 SWC?,F(xiàn)在,我們在 Rust 中使用 SWC 的解析器和 自定義轉(zhuǎn)換 [37] 。這包括完整范圍的提升實(shí)現(xiàn)、依賴項(xiàng)收集等。它的作用范圍類似于 Deno 在 SWC 之上構(gòu)建的方式。” —Devon Govett
這是 Rust 的早期階段——一些重要的部分仍在研究中:
-
插件:對于許多 JavaScript 開發(fā)人員來說,用 Rust 編寫插件并不容易。同時(shí),在 JavaScript 中公開插件系統(tǒng)可能會抵消性能提升。最終的解決方案還沒有出現(xiàn)。理想情況下,未來會結(jié)合 JavaScript 和 Rust。如果你想使用 JavaScript 編寫插件,則可以權(quán)衡速度。需要更多性能?使用 Rust 插件 API。
- 捆綁 :一個有趣的開發(fā)領(lǐng)域
swcpack
是 SWC 替代 webpack。它仍在開發(fā)中,但可能非常有前途。 -
WebAssembly:如上所述,編寫 Rust 并編譯為 WASM 的前景很誘人,但仍有工作要做。
6、結(jié)論
在可預(yù)見的未來,Rust 的受歡迎程度將繼續(xù)增長,并對 JavaScript 生態(tài)系統(tǒng)產(chǎn)生重大影響。想象一下,Next.js 中使用的所有構(gòu)建工具都是用 Rust 編寫的,從而為你提供最佳性能。然后可以將 Next.js 作為從 NPM 下載的 靜態(tài)二進(jìn)制文件 [38] 分發(fā)。對我來說,那將是一個生活(和發(fā)展)的理想世界。