wasm-bindgen 如何使用,nextjs 调用 rust wasm,nextjs 引入 wasm,前端调用 wasm,rust 打包为 wasm 供 js 调用 ,WebAssembly

望舒的头像
望舒 最后修改于
标签:
wasm-bindgenrustwasm

wasm-bindgen 如何使用,nextjs 调用 rust wasm,nextjs 引入 wasm,前端调用 wasm,rust 打包为 wasm 供 js 调用 ,WebAssembly

这里以我写的一个 demo 为案例,使用 rust hex 进行字符串 16 进制编码,打包成 wasm 暴露给 js 调用

实用案例:https://github.com/wangshu-g/nextjs-rust-wasm-example

需要的依赖列表

nextjs 前端不需要任何依赖,本身就是 WebAssembly

需要以下依赖,主要是 wasm-bindgen = "0.2" 这个依赖,打包会自动生成 wasm 文件、javascript 初始化函数、typescript 类型文件

复制
[package]
name = "rust-wasm"
version = "0.1.0"
edition = "2024"

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
panic = "abort"

[dependencies]
hex = "0.4"
wasm-bindgen = "0.2"

[lib]
crate-type = ["cdylib"]

构建打包为 wasm 文件

示例代码,注意 #[wasm_bindgen] ,这是 wasm-bindgen 标识该函数可以作为 wasm 函数调用,没有这个注解的函数不会被暴露

复制
extern crate hex;

use hex::{decode, encode};
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
pub fn get_hex(text: &str) -> String {
    encode(text)
}

#[wasm_bindgen]
pub fn restore_hex(text: &str) -> String {
    String::from_utf8(decode(text).unwrap()).unwrap()
}

在 rust 项目根目录执行 wasm-pack build --target web --release 命令,把生成的 pkg 文件夹复制到你的前端项目即可

复制
wasm-pack build --target web --release

在 nextjs 中初始化,调用 wasm 函数

初始化直接调用 pkg 文件夹 js 文件中的 __wbg_init 函数就可以了,初始化完成后,js 文件中其他的 wasm 函数就可以正常调用了

复制
import React, {useCallback, useEffect, useState} from "react";
import __wbg_init, {get_hex} from "@/pkg/rust_wasm";

const divStyle = {color: "white", padding: 20}
const textareaStyle = {width: "100%", height: 300, border: "1px solid #fff", padding: 20}

export default function WasmPage() {

    const [hex, setHex] = useState<string>("")

    useEffect(() => {

        async function func() {
            if (typeof window !== "undefined" && typeof document !== "undefined") {
                await __wbg_init().then(() => {
                    console.log("wasm load end")
                    setHex(get_hex("hello world"))
                })
            }
        }

        func()
    }, []);

    const handleChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>((e) => {
        setHex(get_hex(e.target.value))
    }, [])

    return <div style={divStyle}>
        原始字符串
        <br/>
        <br/>
        <textarea defaultValue={"hello world"} style={textareaStyle} placeholder={"输入文本"} onChange={handleChange}/>
        <br/>
        <br/>
        通过 wasm 调用 rust hex::encode
        <br/>
        <br/>
        <textarea readOnly style={textareaStyle} placeholder={"hex by rust wasm"} value={hex}/>
    </div>
}

‌‌‌‌‌​​‌​‌​​‌​‌‌‌​​‌​‌​‌​​‌‌​​​‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌​‌​​​‌​​​​​​​​​‌‌​‌‌‌​​‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​​‌​‌‌‌​‌‌‌​​‌‌‌‌‌‌​‌‌‌​‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌​‌‌‌‌​‌‌‌‌​‌​‌‌‌​‌‌‌​​‌‌‌​‌‌​‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌‌‌‌​​‌​‌‌‌​‌‌‌‌‌‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌​‌‌‌​‌‌‌‌​​‌‌‌‌‌​‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌‌​‌​‌​​​‌​​​‌​‌‌‌​​‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​​‌​‌​​‌​‌‌​​‌​​‌​‌‌‌​‌‌​‌​‌‌​‌‌​‌​‌‌‌‌​‌​​​‌​​​‌​​​​​​​​​‌‌​‌‌‌​​‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​​‌​‌‌‌​‌‌‌​​‌‌‌‌‌‌​‌‌‌​‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌​‌‌‌‌​‌‌‌‌​‌​‌‌‌​‌‌‌​​‌‌‌​‌‌​‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌‌‌‌​​‌​‌‌‌​‌‌‌‌‌‌‌‌‌​‌​‌‌‌​‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌​‌‌‌​‌‌‌‌‌‌‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌​‌‌‌​‌‌‌‌​​‌‌‌‌‌​‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​​‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌‌​‌​‌​​​‌​​​‌​‌‌‌​​‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​​‌​‌‌‌​‌‌‌​​‌‌‌‌‌‌​‌‌‌​‌‌‌​​‌‌‌​‌‌‌‌‌‌​‌‌‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​​‌‌‌​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌‌‌‌​​‌​‌​​‌​‌‌‌​​​​​​‌‌​‌‌​​‌‌‌​​​​‌​‌‌​‌‌​‌‌‌‌​‌‌​​​​‌​‌​‌​​​‌‌‌‌‌​​​​‌​‌​‌​‌‌​​‌​‌​‌​​‌‌​‌​​​​‌‌​‌​​​‌‌​​‌​‌‌‌‌‌​​‌​​‌​‌​‌​​​​​‌‌​‌​‌​‌​‌​​​​​‌‌‌‌​‌‌‌​​​​​​​‌‌‌‌​‌‌​​‌‌​​​‌​‌​​​​​​​​‌‌​​​‌​‌‌‌​​​‌​​​​‌​​‌​​‌​‌​​‌​‌‌‌​‌‌​‌​​‌​‌​‌​​‌‌​​​‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌​‌​‌‌‌​‌​‌​‌​‌​​​‌​‌‌‌​‌​‌​​‌‌​‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌‌‌‌‌​​‌‌‌​‌‌​‌‌‌‌‌‌‌​​‌​‌​​‌​‌‌
0
0
0
44
No data