初探網頁開發者該怎麼學 Rust?
目錄
思考學習一個新語言的方式
進到了 Rust 的章節,這幾天反覆思考對於一個完全沒寫過 Rust 的網頁開發者如我來說,怎麼樣才是適合的學習方式。稍微整理了下覺得可以先問問自己這些問題。
為什麼想學 Rust?
- 看近期有許多網頁前端工具被 Rust 化,效能比以往工具突出許多,想知道為什麼 Rust 這麼強
- 熟悉的領域一直深入去鑽有點膩,想來學學新東西重拾初學的樂趣
- 雖然工作上可能用不到,但多學會一個語言或許能讓自己未來學習上有舉一反三的能力
學習上每個階段的 checkpoint 是什麼?
- 階段一:可以知道 Rust 相關的工具怎麼用
- 階段二:先能寫出 Rust 版的 hello world
- 階段三:能寫出一個 Rust 玩具函式,或拿來寫一些 leetcode easy 的題目
- 階段四:能寫出一個 Rust CLI 工具
- 階段五:能理解一些 Rust 的進階觀念(所有權、生命週期等)
- 階段六:能應用 Rust 生態系開發專案
- 階段七:能看懂開源工具的原始碼
- 階段八:能對 Rust-based 開源工具發 PR
就像學習 JavaScript 一樣,一定也是先學會剪剪貼貼做出一個網頁,才回頭理解基礎語法,再逐漸擴大到大型專案並去理解一些語言的眉角,真的對某個工具的問題有興趣才去鑽原始碼,或許這個「先知道怎麼用再學原理」是個不錯的方式。
怎麼學比較快?
- 直接以假裝自己懂 Rust 的心態去看一下開源工具原始碼,越級打怪看一下自己的不足在哪?最終的目標在哪?
- 找一些中文入門教材跟著做,像是龍哥的《為你自己學 Ru.....st》
- 參考官方文件學習(也有繁體中文版)
- 搭配 GAI 工具請它教學一起 pair programming,有問題的地方問到自己可以理解
- 看影片教學,看到 Kyle 在這篇文章中有推薦幾個不錯的學習資源:
要學到什麼程度才夠?
- 以這個系列來說期待可以到階段四或五差不多
- 未來如果有興趣繼續研究希望可以再繼續往其他階段邁進
響應上面越級打怪的學習方式,今天我就試著以終為始先試著了解自己的目標在哪裡吧,直接先在不會 Rust 的狀況下來追追看 Rolldown 的原始碼。
![Chiikawa large beast mission](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fchiikawa.png&w=1200&q=75)
來追追看 Rolldown 的原始碼
以成熟度來說 Rspack 應該更完整,而且現在也能開箱即用,而選擇 Rolldown 的原因是因為目前開發階段相對早期,在想可能程式碼看起來更單純。況且前面都在研究 Vite,直接一脈相承繼續研究下來可能更有發 PR 的機會。
下載專案
不免俗地一樣先把 Rolldown 給載下來:
$ git clone https://github.com/rolldown/rolldown.git --depth=3
尋找進入點
有了前面追 Vite 原始碼的經驗,現在可以更熟悉地知道直接往其中的 packages/rolldown 追進去,稍微瀏覽了這個資料夾底下會發現幾乎都是 TypeScript 檔案,跟前面在看 Vite 沒兩樣,但看 GitHub 上說明的原始碼組成這個 codebase 裡應該有很多 Rust 才對,所以代表這個地方只是最上層的應用層:
![typescript github percentage](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fdemo-1.png&w=1200&q=75)
這時試著在 VS Code 去搜尋檔案,會看到 Rust 檔案幾乎都放在一個叫做 crates 的資料夾下:
![rust files in crates folder](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fdemo-2.png&w=1200&q=75)
這裡我就感到困惑了,如果說 package/rolldown
裡放的是上層應用的邏輯,而這個 crates
裡可能指的是用 Rust 寫出來的一些模組或 plugin 讓上層去引用,但上層又是怎麼去引用的呢?
請 AI 幫忙解惑看看
沒有頭緒下稍微問一下 Cursor 的 inline AI chat:
![cursor AI chat demo](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fcursor-2.png&w=1200&q=75)
第一個 prompt 下得不好,它有提到 crates
底下的結構,但沒有解答我的疑惑,再試一次:
![cursor AI chat demo with new prompt](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fcursor-2.png&w=1200&q=75)
看起來這就是我們要的了!
💡Cursor 是一套基於 VS Code 的 AI editor,對細節有興趣歡迎參考我之前寫過的文章 —— 《Cursor:下一代開發者的 AI 武器》
回到 package.json
回到原本的 packages/rolldown/package.json 裡可以看到一些端倪:
"scripts": {
"# Scrips for binding #": "_",
"build-binding": "napi build -o=./src --manifest-path ../../crates/rolldown_binding/Cargo.toml --platform -p rolldown_binding --js binding.js --dts binding.d.ts --no-const-enum",
"...": "..."
}
"devDependencies": {
"@napi-rs/cli": "^3.0.0-alpha.60",
"@napi-rs/wasm-runtime": "^0.2.4",
"@rolldown/testing": "workspace:*",
"rolldown": "workspace:*",
"...": "..."
},
"optionalDependencies": {
"@rolldown/binding-darwin-arm64": "workspace:*",
"@rolldown/binding-darwin-x64": "workspace:*",
"@rolldown/binding-freebsd-x64": "workspace:*",
"@rolldown/binding-linux-arm-gnueabihf": "workspace:*",
"@rolldown/binding-linux-arm64-gnu": "workspace:*",
"@rolldown/binding-linux-arm64-musl": "workspace:*",
"@rolldown/binding-linux-x64-gnu": "workspace:*",
"@rolldown/binding-linux-x64-musl": "workspace:*",
"@rolldown/binding-wasm32-wasi": "workspace:*",
"@rolldown/binding-win32-arm64-msvc": "workspace:*",
"@rolldown/binding-win32-ia32-msvc": "workspace:*",
"@rolldown/binding-win32-x64-msvc": "workspace:*"
}
這裡看到有個叫 napi
的工具在幫忙在執行指令 build-bindling
後做一些 Node.js 與 Rust 之間綁定的工作。另外在其中安裝的套件中有許多是參考自 workspace:*
裡,這應該是利用 pnpm workspace 在做 monorepo 管理的方式,也就是說它會直接參考到目前這個 codebase 底下其他 package 中打包出來的內容。
接著讓我們來看看 napi 這個東西是什麼。
napi
![napi rust crate](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Fnapi-rs.png&w=1200&q=75)
這裡如果去搜尋 napi
的話,可以找到它的用途看起來是可以把原本 Node.js 裡的邏輯抽成模組,並用 Rust 來改寫,最後可以透過這個套件來做橋接,達到將原本 Node.js 專案漸進式提升效能的作用。如果去看到前面在 AI chat 中有提到的 crates/rolldown_binding,可以看到其中有用上 napi
來做 build code 的操作:
fn main() {
use napi_build::setup;
setup();
}
瀏覽一下 Rust 版的 Rolldown
找到 Rust 的原始碼位置與橋接方式後,雖然還沒能看懂 Rust 但稍微去瀏覽下像是 crates/rolldown/src/bundler.rs 或其他比較複雜的檔案,可以看到一些熟悉的語法像是 let
用來宣告變數、fn
用來宣告函式、use
應該是載入模組的方式、也有 async/await
、if
、for
,和一些類似 TypeScript 的型別定義與泛型等等。
但其中也看到許多不熟悉的語法像是 mut
、pub
、impl
、&mut
、match
、vec
等,而且怎麼好像看到了許多類似 reference 的 &
語法,看來可以預期這些東西大概就是學習曲線會拉高的一個坎,截取其中一小段看個感覺:
![rust rolldown](/_next/image?url=%2Fblog%2Frust%2Fhow-to-learn-rust%2Frolldown.png&w=1200&q=75)
期待這系列結束時可以看懂一部份這在寫什麼。
小結
今天開始進入了 Rust 的章節,在搜集了許多資料並實際嘗試後,也全盤地規劃出後續章節的學習地圖,並嘗試一改以往學習新語言時從基本語法開始練起的方式,直接越級打怪追 Rolldown 的原始碼,先看看要打的怪是什麼,之後要學習時才知道哪邊要多注意去弄懂。其中也示範了下我自己平常如何搭配著 AI 工具來學習,對於學全新不熟悉的內容用這些工具可以說是如虎添翼。