Rust 會成為 JavaScript 基礎設施的未來嗎?

語言: CN / TW / HK

關注「 Rust程式設計指北 」,一起學習 Rust,給未來投資

大家好,我是螃蟹哥。

Rust 最初由 Mozilla 建立,是一種快速、可靠、記憶體效率高且非常流行的程式語言,專為提高效能和安全性而設計。它連續 6 年被 Stack Overflow 調查評為最喜愛的程式語言,並在超大規模的公司使用,如 Facebook,蘋果,亞馬遜,微軟和谷歌等用於系統基礎設施、加密和虛擬化。Rust 現在正在取代 JavaScript Web 生態系統的部分內容,例如壓縮 (Terser)、轉譯 (Babel)、格式化 (Prettier)、打包 (webpack)、linting (ESLint) 等等。讓我們深入探討一下為什麼這種趨勢越來越受歡迎和被廣泛採用。

1、Rust 是什麼?

Rust 幫助開發人員編寫記憶體高效的快速軟體。它是 C++ 或 C 等語言的現代替代品,專注於程式碼安全和簡潔的語法。Rust 與 JavaScript 完全不同。JavaScript 嘗試查詢未使用的變數或物件並自動從記憶體中清除它們。這稱為垃圾收集。該語言將開發人員從手動記憶體管理的思考中抽象出來。使用 Rust,開發人員可以更好地控制記憶體分配,而不會像 C++ 那樣痛苦。

“Rust 使用了一種相對獨特的記憶體管理方法,它結合了記憶體‘所有權’的概念。Rust 會跟蹤誰可以讀寫記憶體。它知道程式何時使用記憶體,並在不再需要時立即釋放記憶體。它在編譯時強制執行記憶體規則,幾乎不可能出現執行時記憶體錯誤。你不需要手動跟蹤記憶體。編譯器會處理它。” — Discord [1]

2、Rust 使用情況

除了上述公司之外,Rust 還被用於流行的開源庫,例如:

  • Firecracker [2] (AWS)

  • Bottlerocket [3] (AWS)

  • Quiche [4] (Cloudflare)

  • Neqo [5] (Mozilla)

“Rust 一直是我們團隊的力量倍增器,押注 Rust 是我們做出的最佳決定之一。不僅僅是效能,它的人體工程學和對正確性的關注幫助我們馴服了同步的複雜性。我們可以在型別系統中編碼關於我們系統的複雜不變數,並讓編譯器為我們檢查它們。” — Dropbox [6]

3、從 JavaScript 到 Rust

JavaScript 是使用最廣泛的程式語言,可在每個帶有網路瀏覽器的裝置上執行。在過去的 10 年裡,圍繞 JavaScript 構建了一個龐大的生態系統:

  • Webpack:開發人員希望將多個 JavaScript 檔案捆綁為一個。

  • Babel:開發人員希望在支援舊瀏覽器的同時編寫現代 JavaScript。

  • Terser:開發人員希望生成儘可能小的檔案。

  • Prettier:開發人員想要一個可以正常工作的固執己見的程式碼格式化程式。

  • ESLint:開發人員希望在部署之前發現他們的程式碼存在的問題。

已經編寫了數百萬行程式碼,並且修復了更多 bug,為當今的 Web 應用程式提供了基礎。所有這些工具都是用 JavaScript 或 TypeScript 編寫的。它們工作得很好,但我們已經達到了 JS 的最佳優化。這激發了一類新的工具,這些工具旨在大幅提高 Web 構建的效能。

SWC

SWC [7] 創建於 2017 年,是一個基於 Rust 的可擴充套件平臺,適用於下一代快速開發工具。它被 Next.js、Parcel 和 Deno 等工具以及 Vercel、位元組跳動、騰訊、Shopify 等公司使用。SWC 可用於編譯、縮小、打包等 - 並且旨在進行擴充套件。你可以呼叫它來執行程式碼轉換(內建或自定義)。通過 Next.js 等更高級別的工具執行這些轉換。

Deno

Deno [8] 創建於 2018 年,是一個簡單、現代且安全的 JavaScript 和 TypeScript 執行時,它基於 V8 [9] 並使用 Rust 構建。它試圖取代由 Node.js 的原始建立者編寫的 Node.js。雖然它是在 2018 年建立的,但直到 2020 年 5 月才釋出 v1.0 [10] 。Deno 的 linter、程式碼格式化程式和文件生成器是 使用 SWC 構建的 [11]

esbuild

esbuild [12] 創建於 2020 年 1 月,是一個 JavaScript 打包器和壓縮器,比用 Go 編寫的其他工具快 10-100 倍。

“我正在嘗試建立一個構建工具,它 a) 適用於給定的最佳用例(打包 JavaScript、TypeScript,也許還有 CSS),b) 重塑社群對 JavaScript 構建意味著工具要快。在我看來,我們目前的工具太慢了。” — Evan [13] ,esbuild 的建立者

在 esbuild 釋出之前,使用 Go 和 Rust 等系統程式語言構建 JavaScript 工具是相當小眾的。在我看來,esbuild 激發了人們更廣泛的興趣,試圖讓開發者工具變得更快。Evan 選擇使用 Go:

“只要付出足夠的努力,Rust 版本能以相同的速度執行。但在高層次上,Go 的工作要愉快得多。這是一個附帶專案,對我來說工作起來一定很有趣。” — Evan,esbuild 的建立者

有人認為 Rust 可以表現得更好,但兩者都可以實現 Evan 影響社群的最初目標:

“即使只有基本的優化,Rust 也能勝過超級手動調整的 Go 版本。與我們必須使用 Go 進行的深入研究相比,這極大地證明了使用 Rust 編寫高效的程式是多麼容易。” —Discord

Rome

Rome [14] 於 2020 年 8 月建立,是一個用於 JavaScript、TypeScript、HTML、JSON、Markdown 和 CSS 的 linter、編譯器、捆綁器、測試執行器等。他們的目標是替換和統一整個前端開發工具鏈。它是由 Sebastian McKenzie [15] 建立的,他之前還建立了 Babel。

那為什麼要重寫一個呢?

“對 Babel 進行必要的修改以使其成為其他工具的可靠基礎將需要對所有內容進行更改。該架構與我在 2014 年學習解析器、AST 和編譯器時所做的初始設計選擇有關。” — Sebastian McKenzie [16]

Rome 目前使用 TypeScript 編寫並在 Node.js 上執行。但是他們現在正在使用 RSLint 解析器和他們自己的訪問者系統來 用 Rust 重寫 [17] 以進行 AST 遍歷。

NAPI

Rust 與 Node.js 的整合優於其他低階語言。 napi-rs [18] 允許你使用 Rust 構建預編譯的 Node.js 外掛。它提供了交叉編譯和釋出本地的二進位制檔案 NPM:一個徹頭徹尾的現成的解決方案,而無需 node-gyppostinstall 指令碼。你可以構建一個可以直接從 Node.js 呼叫的 Rust 模組,而無需建立像 esbuild 這樣的子程序。

Rust + WebAssembly

WebAssembly [19] (WASM) 是 Rust 可以編譯成的一種可移植的低階語言。它在瀏覽器中執行,可與 JavaScript 互操作,並在所有主要的現代瀏覽器中均受支援。

“WASM 肯定比 JS 快很多,但不如原生速度。在我們的測試中,Parcel 編譯為 WASM 時的執行速度比使用原生二進位制檔案慢 10-20 倍。” — Devon Govett

雖然 WASM 還不是完美的解決方案,但它可以幫助開發人員創建極快的 Web 體驗。Rust 團隊 致力於 [20] 高質量和尖端的 WASM 實現。對於開發人員來說,這意味著你可以擁有 Rust(相對於 Go)的效能優勢,同時仍然為 Web 編譯(使用 WASM)。

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

  • Yew [21]

  • Percy [22]

  • Seed [23]

  • Sycamore [24]

  • Stork [25]

這些編譯為 WASM 的基於 Rust 的 Web 框架並沒有試圖取代 JavaScript,而是與它一起工作。雖然我們還沒有到那一步,但有趣的是看到 Rust 在兩個方面都在 Web 之後出現:使現有的 JavaScript 工具更快,併為 編譯為 WASM 提供 [26] 未來的想法。從頭到尾都是 Rust。

4、Rust 有什麼問題?

Rust 學習曲線陡峭,網友戲稱:Rust 入門很容易,我已經入門 4、5 次了。它的抽象級別比大多數 Web 開發人員習慣的要低。一旦你使用本機程式碼(通過 Rust、Go、Zig 或其他低階語言),演算法和資料結構比語言選擇 更重要 [27] 。這不是銀彈。

“Rust 讓你思考對系統程式設計非常重要的程式碼維度。它讓你思考如何共享或複製記憶體。它使你考慮真實但不太可能的極端情況,並確保它們得到處理。它可以幫助你以各種可能的方式編寫極其高效的程式碼。” — Tom MacWright [28]

此外,Rust 在網路社群中的使用仍然是小眾的。它還沒有達到關鍵的使用量。儘管為 JavaScript 工具學習 Rust 將成為入門障礙,但有趣的是,開發人員更願意擁有一個更快的工具,即使為其貢獻程式碼挺難。

目前,很難為NIIT喜歡的服務(例如使用身份驗證、資料庫、支付等)找到一個 Rust 庫或框架。我認為一旦 Rust 和 WASM 獲得關鍵採用,這將自行解決。但目前還不成熟。我們需要現有的 JavaScript 工具來幫助我們彌合差距並逐步採用以改進效能。

5、JavaScript 工具的未來

我相信 Rust 是 JavaScript 工具的未來。 Next.js 12 [29] 開始了我們的過渡,用 SWC 和 Rust 完全替換 Babel(轉譯)和 Terser(壓縮)。為什麼?

  • 可擴充套件性:SWC 可以用作 Next.js 中的 Crate,而無需 fork 庫或解決設計約束。

  • 效能:通過切換到 SWC,我們能夠在 Next.js 中實現約 3 倍的快速重新整理和約 5 倍的構建速度,還有更多的優化空間仍在進行中。

  • WebAssembly:Rust 對 WASM 的支援對於支援所有可能的平臺和在任何地方進行 Next.js 開發至關重要。

  • 社群:Rust 社群和生態系統令人驚歎,而且還在不斷增長。

不僅僅是 Next.js 採用了 SWC:

  • Deno [30] 的 linter、程式碼格式化程式和文件生成器是 使用 SWC 構建的 [31]

  • dprint [32] 建立在 SWC 之上,是 Prettier [33]30 倍 [34] 程式碼格式化替代品。

  • Parcel [35] 使用 SWC 將整體構建效能提高了 10 倍 [36]

“在我們使用 Babel 的解析器和用 JS 編寫的自定義轉換之前,Parcel 像庫一樣使用 SWC。現在,我們在 Rust 中使用 SWC 的解析器和 自定義轉換 [37] 。這包括完整範圍的提升實現、依賴項收集等。它的作用範圍類似於 Deno 在 SWC 之上構建的方式。” —Devon Govett

這是 Rust 的早期階段——一些重要的部分仍在研究中:

  • 外掛:對於許多 JavaScript 開發人員來說,用 Rust 編寫外掛並不容易。同時,在 JavaScript 中公開外掛系統可能會抵消效能提升。最終的解決方案還沒有出現。理想情況下,未來會結合 JavaScript 和 Rust。如果你想使用 JavaScript 編寫外掛,則可以權衡速度。需要更多效能?使用 Rust 外掛 API。

  • 捆綁 :一個有趣的開發領域 swcpack 是 SWC 替代 webpack。它仍在開發中,但可能非常有前途。
  • WebAssembly:如上所述,編寫 Rust 並編譯為 WASM 的前景很誘人,但仍有工作要做。

6、結論

在可預見的未來,Rust 的受歡迎程度將繼續增長,並對 JavaScript 生態系統產生重大影響。想象一下,Next.js 中使用的所有構建工具都是用 Rust 編寫的,從而為你提供最佳效能。然後可以將 Next.js 作為從 NPM 下載的 靜態二進位制檔案 [38] 分發。對我來說,那將是一個生活(和發展)的理想世界。

原文連結:https://thenewstack.io/the-case-for-rust-as-the-future-of-javascript-infrastructure/

參考資料

[1]

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

[2]

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

[3]

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

[4]

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

[5]

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

[6]

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

[7]

SWC: http://swc.rs/

[8]

Deno: https://deno.land/

[9]

V8: https://v8.dev/

[10]

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

[11]

使用 SWC 構建的: https://twitter.com/devongovett/status/1369033422002389000

[12]

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

[13]

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

[14]

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

[15]

Sebastian McKenzie: https://twitter.com/sebmck

[16]

Sebastian McKenzie: https://rome.tools/blog/2020/08/08/introducing-rome

[17]

用 Rust 重寫: https://rome.tools/blog/2021/09/21/rome-will-be-rewritten-in-rust

[18]

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

[19]

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

[20]

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

[21]

Yew: https://yew.rs/

[22]

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

[23]

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

[24]

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

[25]

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

[26]

編譯為 WASM 提供: https://rustwasm.github.io/docs/book/introduction.html

[27]

更重要: https://twitter.com/devongovett/status/1457945506332692482

[28]

Tom MacWright: https://macwright.com/2021/01/15/rust.html

[29]

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

[30]

Deno: https://deno.land/

[31]

使用 SWC 構建的: https://twitter.com/devongovett/status/1369033422002389000

[32]

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

[33]

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

[34]

30 倍: https://twitter.com/devongovett/status/1400138335721455617

[35]

Parcel: https://parceljs.org/

[36]

10 倍: https://v2.parceljs.org/blog/beta3/

[37]

自定義轉換: https://github.com/parcel-bundler/parcel/tree/v2/packages/transformers/js/core/src

[38]

靜態二進位制檔案: https://en.wikipedia.org/wiki/Static_build

推薦閱讀

覺得不錯,點個贊吧

掃碼關注「 Rust程式設計指北