跳到主要内容
Deno 2.4 已发布,带来 deno bundle、字节/文本导入、OTel 稳定版等新特性
了解更多
Ferris the Crab hanging out with the Deno dinosaur on the beach.

wasmbuild - 在 Deno 和 Web 应用中使用 Rust

编写 JavaScript 时,有时调用 Rust 代码会很有用。例如,可能有一个已在 Rust 中实现的复杂算法,您希望复用它,或者某些 Rust 代码可能比任何 JS 实现运行得更快、内存效率更高。

这篇博文将介绍一个名为 wasmbuild 的新工具,它简化了在 Deno 和浏览器中构建和使用 Rust 代码的过程。

概述

wasmbuild 是一个 CLI 工具,它使用 wasm-bindgen 为调用 Rust crate 生成“胶水代码”(glue code)。生成的输出可以通过 WebAssembly 轻松地在 JavaScript 中使用。wasmbuild 包括多种加载器策略、惰性实例化,并使用 wasm-opt 工具自动优化输出。

这与 wasm-bindgen-cliwasm-pack 等工具非常相似,但它是一个脚本,您和您的贡献者无需安装除 Rust 工具链和 Deno 之外的全局 CLI 工具即可运行。此外,它专门针对 Deno 和浏览器。

示例 - 两个整数相加

对于本示例,我们将从头开始创建一个在 Rust 中添加两个数字的函数,然后在我们的 JavaScript 中使用该函数。

前提条件

开始之前

  1. 安装 Deno
  2. 通过 Rustup 安装 Rust

安装完成后,请确保 deno -Vrustup -Vcargo -V 都能正常工作。

设置 Wasmbuild 和 Rust

打开终端,为您的项目创建一个新文件夹,并将当前工作目录更改为该项目内。

mkdir wasmbuild_example && cd wasmbuild_example

在该目录下,创建一个 deno.json 文件,其中为 Deno 的任务运行器定义了 wasmbuild 任务,如下所示

{
  "tasks": {
    "wasmbuild": "deno run -A https://deno.land/x/wasmbuild@0.8.5/main.ts"
  }
}

现在,使用 new 参数运行该任务

deno task wasmbuild new

这将在您项目的 rs_lib 文件夹中搭建一个 Rust crate 启动模板,并包含一个示例函数

// rs_lib/src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
  return a + b;
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn it_works() {
    let result = add(1, 2);
    assert_eq!(result, 3);
  }
}

该文件定义了一个名为 add 的函数,它接受两个有符号整数并返回一个有符号整数。然后,它通过 #[wasm_bindgen] 属性导出,以供 JavaScript 使用。

在本示例中,我们将继续使用此生成代码。

构建

要构建项目,请运行 wasmbuild 任务

deno task wasmbuild

这将创建一个 lib/rs_lib.generated.js 文件和 lib/rs_lib_bg.wasm 文件。

在 Deno 中使用

要在 Deno 中使用它,请创建一个 main.js 文件,其中包含以下代码

import { instantiate } from "./lib/rs_lib.generated.js";

const { add } = await instantiate();

console.log(add(1, 2));

这将实例化 Wasm 模块,调用其 add 函数,并将结果输出到控制台。

运行以下命令试用:

deno run main.js

输出应为 3

在浏览器中使用

创建一个非常基础的 index.html 文件,它引用了我们之前创建的 main.js 文件

<html>
  <script type="module" src="main.js"></script>
</html>

现在启动一个 HTTP 服务器,它将提供当前工作目录中的文件。我们可以通过运行以下命令轻松做到这一点

$ deno run --allow-net --allow-read=. https://deno.land/std@0.144.0/http/file_server.ts
Listening on https://:4507/

导航到所示链接以提供 index.html 文件,并打开浏览器控制台。您应该会在控制台中看到 3

在 Deno Deploy 中使用

除了 Deno 的 CLI 和浏览器之外,wasmbuild 生成的代码在 Deno Deploy 上也能直接运行。

这里有一个使用上述示例的 playground(点击“Open Editor”即可查看运行效果)

这从 https://github.com/denoland/wasmbuild_example 仓库导入了上述生成代码,实例化 Wasm 模块以获取 add 函数,然后启动一个 Web 服务器,该服务器响应每个请求时都返回 12 相加的结果。

通常,使用 Deno Deploy 时,您会希望使用 Git 集成来部署此代码。请注意,目前通过 URL 部署无法与 wasmbuild 的生成输出配合使用,因为 .wasm 文件不是模块图(module graph)的一部分。一旦 Wasm 模块可以被导入,这个问题就会得到修复,如果您对此感兴趣,请关注 issue #2552 以获取更新。

更多详情

上述所有代码均可在以下链接获取: https://github.com/denoland/wasmbuild_example

有关 wasmbuild 的更多信息,请参阅以下仓库: https://github.com/denoland/wasmbuild