前言
在現代 Web 開發中,WebAssembly (WASM) 已成為一種強大的工具。它使得開發者可以在瀏覽器中執行高效能的程式碼,跨越傳統的 JavaScript 效能限制。Rust 語言因其高效性和記憶體安全性,成為了編寫 WASM 模組的熱門選擇。本文將介紹如何將 Rust 程式碼編譯為 WebAssembly,並在 Web 專案中使用。
1. 建立 Rust 專案
首先,我們需要建立一個新的 Rust 專案。由於我們要生成一個可以被其它語言或工具呼叫的模組,因此選擇建立一個庫專案,而不是可執行程式。使用 cargo
命令可以輕鬆完成:
cargo new lib_wasm --lib
這個命令會生成一個名為 lib_wasm
的專案,其中包含一個基礎的 Cargo.toml
配置檔案和一個 src/lib.rs
檔案,你將在其中編寫你的 Rust 程式碼。
2. 新增 wasm-bindgen
依賴項
在 Rust 中,wasm-bindgen
是一個關鍵工具,它使 Rust 和 JavaScript 之間的互動變得更加簡單。wasm-bindgen
負責生成與 JavaScript 互動所需的繫結程式碼,讓你能夠直接呼叫 Rust 編寫的函式。
要新增 wasm-bindgen
,你可以使用 cargo add
命令:
cargo add wasm-bindgen
或者,手動編輯 Cargo.toml
檔案,新增如下依賴項:
[dependencies]
wasm-bindgen = "0.2"
新增 wasm-bindgen
後,Rust 編譯器會在編譯過程中生成必要的繫結檔案,從而使你的 WASM 模組可以被 JavaScript 直接呼叫。
3. 安裝 wasm32-unknown-unknown
目標
Rust 編譯器預設會生成適用於本地機器架構的可執行檔案。要編譯成適用於 Web 的 WebAssembly 檔案,我們需要新增一個特定的目標架構,即 wasm32-unknown-unknown
。這是一個通用的 WASM 目標,不依賴任何特定的作業系統。
使用以下命令安裝該目標:
rustup target add wasm32-unknown-unknown
此命令會配置你的 Rust 工具鏈,使其能夠生成適用於 WebAssembly 的二進位制檔案。
4. 編寫 Rust 程式碼
現在,你可以在 src/lib.rs
檔案中編寫你希望匯出的功能。例如,我們可以編寫一個簡單的函式,它接受一個名字作為引數並返回一個問候語:
use wasm_bindgen::prelude::*;
// 使用 #[wasm_bindgen] 宏來匯出函式到 JavaScript
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
在這段程式碼中,我們使用了 #[wasm_bindgen]
宏將 greet
函式匯出,使其可以從 JavaScript 中呼叫。
5. 編譯 Rust 專案為 WASM
編寫完程式碼後,我們可以將其編譯為 WASM 檔案。編譯時指定目標為 wasm32-unknown-unknown
,並使用 --release
選項生成最佳化後的構建:
cargo build --target wasm32-unknown-unknown --release
編譯完成後,生成的 .wasm
檔案將儲存在 target/wasm32-unknown-unknown/release/
目錄下。
6. 使用 wasm-bindgen
生成 JavaScript 繫結程式碼
雖然編譯生成了 .wasm
檔案,但直接在 JavaScript 中使用它並不方便。為此,我們需要使用 wasm-bindgen
工具生成相應的 JavaScript 繫結程式碼。這將建立一個便於在 JavaScript 中呼叫的模組。
首先,確保已安裝 wasm-bindgen-cli
工具。你可以透過以下命令安裝:
cargo install wasm-bindgen-cli
然後,執行以下命令生成 JavaScript 繫結檔案:
wasm-bindgen --out-dir ./out --target web target/wasm32-unknown-unknown/release/lib_wasm.wasm
這會在 out
目錄中生成一系列檔案,包括 .js
檔案和 .wasm
檔案,你可以直接在 Web 專案中使用。
7. 在網頁中使用 WASM 模組
現在,生成的 WASM 模組已經可以在 Web 專案中使用。你只需在 HTML 檔案中匯入生成的 JavaScript 繫結檔案,並呼叫 Rust 匯出的函式。例如:
<!DOCTYPE html>
<html>
<head>
<title>Lib WASM Demo</title>
</head>
<body>
<script type="module">
import init, { greet } from "./out/lib_wasm.js";
init().then(() => {
console.log(greet("World"));
});
</script>
</body>
</html>
這個示例會在控制檯列印出 "Hello, World!"。其中,init
函式用於初始化 WASM 模組,而 greet
函式則呼叫了我們在 Rust 中定義的函式。
web 專案目錄結構如下:
index.html
out/
├── lib_wasm_bg.wasm
├── lib_wasm_bg.wasm.d.ts
├── lib_wasm.d.ts
└── lib_wasm.js
out
目錄中包含了生成的 WASM 檔案以及相應的 JavaScript 繫結檔案,index.html
是一個簡單的網頁,用於測試和展示你的 WASM 模組。
結語
透過這套流程,你可以輕鬆地將 Rust 程式碼編譯為 WebAssembly,並將其整合到 Web 專案中。Rust 的高效性和 WebAssembly 的靈活性相結合,可以為 Web 應用帶來顯著的效能提升。