將 Rust 程式碼編譯為 WASM

_zhiqiu發表於2024-08-14

前言

在現代 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 應用帶來顯著的效能提升。

相關文章