對比著 Npm 來學(xué) Rust 的 Cargo,一遍就會了
我們寫 Node.js 代碼離不開的是什么,是 Npm。這就像寫 Rust 代碼離不開 Cargo 一樣。
大家可能不了解 Rust 和 Cargo。沒關(guān)系,接下來我們就對照著 npm 來學(xué)習(xí)下 Cargo,幫大家入門下 Rust。
我們先從熟悉的 Node.js 開始:
寫 Node.js 代碼的流程
我們會先創(chuàng)建一個目錄,然后在目錄下執(zhí)行 npm init
- mkdir node-pro
- cd node-pro
- npm init
控制臺會交互式的詢問一些信息,然后生成 package.json
也可以加上 -y 用默認(rèn)值快速創(chuàng)建。
之后我們會用 npm install xxx 來安裝依賴,比如安裝 babel
- npm install babel
這時候 package.json 的 dependencies 下就有了 babel 的依賴信息
同時會生成一個 package-lock.json 記錄依賴版本(用 yarn 安裝的話就是 yarn.lock 文件)
依賴會安裝在 node_modules 下。
之后呢,我們會創(chuàng)建 src,寫一些代碼。
然后在 package.json 的 scripts 中指定編譯、測試等腳本:
然后代碼寫完以后,通過 npm run build 來跑構(gòu)建、通過 npm run test 來跑測試:
- npm run build
- npm run test
生成的產(chǎn)物可以通過 npm publish 發(fā)布到 npm 倉庫。
過程中可能還用到一些其他的命令:比如要更新依賴會用 npm update,比如要搜索依賴用 npm search 等。
這就是一個 Node.js 項目的開發(fā)流程,拋開具體寫的 Node.js 代碼不談,整個工具鏈?zhǔn)怯?npm 串聯(lián)的。
你可能會說這個很基礎(chǔ)啊,不是入門的內(nèi)容么?
是的,npm 是 Node.js 入門要學(xué)的,那么同樣,入門 Rust 也要先學(xué) Cargo。
而且,npm 和 cargo 的設(shè)計特別的像,幾乎看一遍大家就會了。
那還等什么,趕緊來學(xué)一下 Cargo 吧。
寫 Rust 代碼的流程
和 Node.js 項目一樣,可以先創(chuàng)建目錄,然后使用 cargo init 初始化代碼(這里也可以直接使用 cargo new,效果和下面 mkdir + cargo init 一樣)
- mkdir rust-pro
- cd rust-pro
- cargo init
然后就會創(chuàng)建這樣的目錄結(jié)構(gòu):
cargo.toml 相當(dāng)于 package.json,也是聲明包信息和 dependencies 的。
而且連 src 都有了, git 也初始化了,這比 npm init 更貼心啊(難怪大家都喜歡 rust,這工具鏈做的多細(xì))。
cargo.toml 的內(nèi)容是這樣的:
[package] 下聲明的是包的信息,[dependencies] 下聲明的是依賴信息。
我們用 cargo search 搜索下某個包(相當(dāng)于 npm search):
可以搜到 html2md 的版本是 0.2.13,我們把它填到依賴?yán)铮?/p>
之后我們寫點代碼,把 html 轉(zhuǎn)成 markdown:
然后,編譯和執(zhí)行:
- cargo build
- cargo run
就可以看到執(zhí)行結(jié)果:
我們用 npm run build 執(zhí)行的也是構(gòu)建命令,只不過是自己配置的三方編譯工具,而 cargo 是用內(nèi)置的編譯工具。
這樣我們就跑起來了第一個 rust 程序。是不是流程和 npm 有那么一丟丟的像。
而且,像 yarn.lock 或者 package-lock.json 一樣,cargo 也有 Cargo.lock 來記錄了依賴的具體信息:
后續(xù)也可以執(zhí)行 cargo test 來跑測試代碼,可以執(zhí)行 cargo publish 來上傳到中央倉庫。和 npm 的整體流程比較類似。
Npm 和 Cargo 相似的原因
為什么 cargo 和 npm 這么類似呢?
這說明這已經(jīng)是最佳實踐了!也就是把 init 的腳手架、編譯構(gòu)建、運行、測試、發(fā)布等功能集成到一個命令中工具中,內(nèi)置到語言的工具鏈。
對照下古老的 C++ 就能看出區(qū)別:
C++ 使用 clang 或者 gcc 編譯,其他的功能并沒有,需要結(jié)合 cmake 來聲明一些其他的命令。最關(guān)鍵的是沒有中央的倉庫和依賴管理工具,每個依賴都要手動下載,然后放到項目目錄下,特別麻煩。
既然這是必備功能,為什么不內(nèi)置到語言的工具鏈呢?
所以 npm 和 cargo 都把 init、install、update、build、test、publish 等命令內(nèi)置了,而且也都支持了中央倉庫和依賴管理。
這是現(xiàn)代的語言工具鏈的最佳實踐了,用別的現(xiàn)代語言的工具也會感覺差不多。
總結(jié)
Cargo 之于 Rust 就像 Npm 之于 Node.js,兩者都是初始化、依賴管理、構(gòu)建、發(fā)布、等的集成的命令行工具鏈。
Node.js 的項目的開發(fā)流程是這樣的:
- npm init 初始化項目
- npm search 搜索依賴
- npm install 安裝依賴
- npm update 升級依賴
- npm run build 執(zhí)行構(gòu)建
- npm run test 執(zhí)行測試
- npm publish 發(fā)布到中央倉庫
Rust 項目的開發(fā)流程也類似:
- cargo init 初始化項目 (或者 cargo new,這個相當(dāng)于 mkdir + cargo init)
- cargo search 搜索依賴
- cargo install 安裝依賴
- cargo update 升級依賴
- 手動把依賴填到 Cargo.toml 中
- cargo build 編譯構(gòu)建代碼
- cargo run 運行代碼
- cargo test 跑單元測試
- cargo publish 發(fā)布到中央倉庫
雖然具體的語法不同,項目結(jié)構(gòu)也有差別,但是整個工具鏈的流程是類似的。這是現(xiàn)代語言工具鏈的最佳實踐了。
相比之下,C++ 沒有依賴管理,沒有集成的工具鏈,開發(fā)體驗遠(yuǎn)遠(yuǎn)比不上有 Cargo 的 rust 和有 npm 的 Node.js。
其實我們學(xué)習(xí) rust 或其他語言,都可以對比我們熟悉的 JS 來學(xué),因為他們只是使用計算機(jī)的不同的抽象,面對的問題差不多,只不過解法不同,對比著學(xué)習(xí),效率會更高。
對比著 Npm 來學(xué) Cargo,是不是看一遍就會了~