美文网首页
wasm与JS交互

wasm与JS交互

作者: 天問_专注于大前端技术 | 来源:发表于2022-01-16 22:42 被阅读0次

    最近我们已经见识了WebAssembly如何快速编译、加速JS库以及生成更小的二进制格式。我们甚至为Rust和JavaScript社区以及其他Web编程语言之间的更好的互操作性制定了高级规划。正如前面一篇文章中提到的,我想深入了解一个特定组件的细节,wasm-bindgen。

    今天WebAssembly标准只定义了四种类型:两种整数类型和两种浮点类型。然而,大多数情况下,JS和Rust开发人员正在使用更丰富的类型! 例如,JS开发人员经常与互以添加或修改HTML节点相关的文档交互,而Rust开发人员使用类似Result等类型进行错误处理,几乎所有程序员都使用字符串。

    被局限在仅使用由WebAssembly所提供的类型将会受到太多的限制,这就是wasm-bindgen出现的原因。

    wasm-bindgen的目标是提供一个JS和Rust类型之间的桥接。它允许JS使用字符串调用Rust API,或Rust函数捕获JS异常。

    wasm-bindgen抹平了WebAssembly和JavaScript之间的阻抗失配,确保JavaScript可以高效地调用WebAssembly函数,并且无需boilerplate,同时WebAssembly可以对JavaScript函数执行相同的操作。

    wasm-bindgen项目在其README文件中有更多描述。要入门,让我们深入到一个使用wasm-bindgen的例子中,然后探索它还有提供了什么。

    1、Hello World!

    学习新工具的最好也是最经典的方法之一就是探索下用它来输出“Hello, World!”。在这里,我们将探索一个这样的例子——在页面里弹出“Hello World!”提醒框。

    这里的目标很简单,我们想要定义一个Rust的函数,给定一个名字,它会在页面上创建一个对话框,上面写着Hello,$name!在JavaScript中,我们可以将这个函数定义为:

    代码

    export function greet(name) {undefined

    alert(Hello, ${name}!);

    }

    不过在这个例子里要注意的是,我们将把它用Rust编写。这里已经发生了很多我们必须要处理的事情:

    JavaScript将会调用一个WebAssembly 模块, 模块名是 greetexport.

    Rust函数将一个字符串作为输入参数,也就是我们要打招呼的名字。

    在内部Rust会生成一个新的字符串,也就是传入的名字。

    最后Rust会调用JavaScript的 alert函数,以刚创建的字符串作为参数。

    启动第一步,我们创建一个新的Rust工程:

    代码

    $ cargo new wasm-greet --lib

    这将初始化一个新的wasm-greet文件夹,我们的工作都在这里面完成。接下来我们要使用如下信息修改我们的Cargo.toml(在Rust里相当于package.json):

    代码

    [lib]

    crate-type = ["cdylib"]

    [dependencies]

    wasm-bindgen = "0.2"

    我们先忽略[lib]节的内容,接下来的部分声明了对wasm-bindgen的依赖。这里的依赖包含了我们使用wasm-bindgen需要的所有的支持包。

    接下来,是时候编写一些代码了!我们使用下列内容替换了自动创建的src/lib.rs:

    代码

    ![feature(proc_macro, wasm_custom_section, wasm_import_module)]

    extern crate wasm_bindgen;

    use wasm_bindgen::prelude::*;

    [wasm_bindgen]

    extern {undefined

    fn alert(s: &str);

    }

    [wasm_bindgen]

    pub fn greet(name: &str) {undefined

    alert(&format!("Hello, {}!", name));

    }

    如果你不熟悉Rust,这可能看起来有点啰嗦,但不要害怕!随着时间的推移,wasm-bindgen项目不断改进,而且可以肯定的是,所有这些并不总是必要的。

    要注意的最重要的一点是#[wasm_bindgen]属性,这是一个在Rust代码中的注释,这里的意思是“请在必要时用wrapper处理这个”。我们对alert函数的导入和greet函数的导出都被标注为这个属性。稍后,我们将看到在引擎盖下发生了什么。

    首先,我们从在浏览器中打开作为例子来切入正题!我们先编译wasm代码:

    代码

    $ rustup target add wasm32-unknown-unknown --toolchain nightly # only needed once

    $ cargo +nightly build --target wasm32-unknown-unknown

    这段代码会生成一个wasm文件,路径为target/wasm32-unknown-unknown/debug/wasm_greet.wasm。如果我们使用工具如wasm2wat来看这个wasm文件里面的内容,可能会有点吓人。

    结果发现这个wasm文件实际上还不能直接被JS调用!为了能让我们使用,我们需要执行一个或更多步骤:

    代码

    $ cargo install wasm-bindgen-cli # only needed once

    $ wasm-bindgen target/wasm32-unknown-unknown/debug/wasm_greet.wasm --out-dir .

    很多不可思议的事情发生都发生在这个步骤中:wasm-bindgen CLI工具对输入的wasm文件做后期处理,使它变的“suitable”可用。

    我们待会再来看“suitable”的意思,现在我们可以肯定的说,如果我们引入刚创建的wasm_greet.js文件(wasm-bindgen工具创建的),我们已经获取到了在Rust中定义的greet函数。

    最终我们接下来要做的是使用bundler对其打包,然后创建一个HTML页面运行我们的代码。

    相关文章

      网友评论

          本文标题:wasm与JS交互

          本文链接:https://www.haomeiwen.com/subject/iquqhrtx.html