rust开发wasm与浏览器(js)交互

效果

1.流程图

HTML按钮 | v JavaScript | v md5_encrypt("hello wasm") || start("hello from javascript") | v Rust WASM | v md5::compute() || format!(""); | v 返回32位hash

2.效果图

前言

使用rust的lib开发库,给js调用,js是使用了原生简单编写一下交互效果,然后使用了docker(docker-compose)进行运行

开始

项目架构图

web-project ├── docker-compose.yml ├── frontend【原生前端】 ├── wasm【rust库】

docker-compose.yml

services: nginx: image: nginx:latest container_name: wasm-nginx ports: - "8080:80" volumes: - ./frontend:/usr/share/nginx/html:ro restart: always
docker compose up -d

frontend

项目架构图

web-project\frontend ├── index.html └── pkg ├── wasm.d.ts ├── wasm.js ├── wasm_bg.wasm └── wasm_bg.wasm.d.ts

pkg是rust打包的目录【由rust生成】

index.html

<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>Rust WASM Demo</title> <style> body { font-family: Arial; padding: 40px; } button { padding: 10px 20px; font-size: 16px; cursor: pointer; } #result { margin-top: 20px; padding: 15px; background: #f5f5f5; border-radius: 5px; } </style> </head> <body> <div> <div> <h1>Rust WASM 浏览器交互</h1> </div> <div> <button id="btn">调用 Rust 方法</button> <button id="md5Btn">MD5加密</button> </div> <div id="result">等待调用...</div> </div> </body> <script type="module"> import init, {start, md5_encrypt} from "./pkg/wasm.js"; let wasmReady = false; async function initWasm(){ await init(); wasmReady = true; console.log("Rust WASM加载完成"); } initWasm(); const btn = document.getElementById("btn"); const result = document.getElementById("result"); const md5Btn = document.getElementById("md5Btn"); btn.onclick = function() { if(!wasmReady){ result.innerHTML = "WASM还未加载"; return; } // 调用 Rust 方法 let rustResult = start("hello from javascript"); // 显示 Rust 返回结果 result.innerHTML = rustResult; }; md5Btn.onclick = function () { let rustResult = md5_encrypt("hello wasm"); console.log("===md5===", rustResult); // 显示 Rust 返回结果 result.innerHTML = rustResult; }; </script>

wasm

rustc --version cargo --version rustup --version 需要的依赖 rustup install stable rustup target add wasm32-unknown-unknown cargo install wasm-bindgen-cli 创建lib库项目 cargo new wasm --lib

项目架构图

web-project\wasm ├── Cargo.lock ├── Cargo.toml ├── pkg | ├── wasm.d.ts | ├── wasm.js | ├── wasm_bg.wasm | └── wasm_bg.wasm.d.ts ├── src | ├── lib.rs | └── main.rs

Cargo.toml

[package] name = "wasm" version = "0.1.0" edition = "2024" [lib] crate-type = ["cdylib", "rlib"] [dependencies] wasm-bindgen = "0.2" md5 = "0.7"

src/lib.rs

use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn start(str_input: String) -> String { let result = format!("Rust wasm received: {}", str_input); result } // MD5加密方法 #[wasm_bindgen] pub fn md5_encrypt(input: String) -> String { let digest = md5::compute(input.as_bytes()); format!("{:x}",digest) } // #[cfg(test)] // mod tests { // use super::*; // #[test] // fn test_start() { // let result = start("hello".to_string()); // assert_eq!(result,"Rust wasm received: hello"); // } // }

src/main.rs

用cargo run 来测试lib库的方法

fn main() { let str = "hello cargo run"; let result = wasm::start(str.to_string()); println!("{}",result); }

pkg是打包生成的

打包成wasm文件 cargo build --target wasm32-unknown-unknown --release 生成到pkg wasm-bindgen --target web --out-dir pkg target/wasm32-unknown-unknown/release/wasm.wasm

总结

先是rust开发好lib库,然后打包成pkg,在给到前端(javaScript)调用,前端资源使用docker-compose运行