☰
wasm-bindgen 官方示例全览:基于 `wasm-bindgen`、`js-sys` 与 `web-sys` 的实战入门指南
2026/10/6 2:03:29 网站建设 项目流程
  • 开发工具

【免费下载链接】wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript

项目地址:https://gitcode.com/gh_mirrors/wa/wasm-bindgen
点击查看免费下载

wasm-bindgen仓库的 guide/src/examples/index.md 是官方示例子章节的入口文档,它并不讲解某个单一 API,而是系统性地介绍wasm-bindgen、js-sys、web-sys三大 crate 的示例集合:示例在哪里、如何运行、如何构建、以及如何将 Rust + WebAssembly 产物部署到不同环境。本文以该文档为主体骨架,结合仓库中 examples 目录下的真实工程(源码、package.json、webpack 配置)与 部署指南,把「阅读示例 → 本地运行 → 理解构建目标 → 选择部署方案」这条完整链路讲透,帮助读者快速上手并动手修改自己的示例工程。

示例集合是什么:三大 crate 的实战用法

仓库中wasm-bindgen、js-sys和web-sys三个 crate 分别承担不同职责:

  • wasm-bindgen:提供#[wasm_bindgen]属性宏、wasm_bindgen::prelude、JsValue等核心设施,负责 Rust 类型与 JavaScript 类型之间的桥接;
  • js-sys:封装 ECMAScript 标准库对象(Array、Promise、Date、JSON等);
  • web-sys:封装 Web API(DOM、Canvas、WebGL、WebRTC、Web Audio 等,仓库 web-sys/src 下即包含上千个按 WebIDL 生成的绑定模块)。

官方文档明确指出:每个示例都应附带关于它具体做了什么的信息,这正是 examples 目录中每个子工程自带 README 的原因——例如 hello_world 示例的 README 会说明构建命令和访问地址。示例覆盖了add、canvas、char、closures、console_log、dom、fetch、julia_set、paint、performance、todomvc、webaudio、webgl、webrtc_datachannel、websockets、webxr、nodejs-threads、wasm-in-wasm、without-a-bundler等数十个场景,从「最小 Hello World」到「并行光线追踪(raytrace-parallel)」「显式资源管理(explicit-resource-management)」「JSPI(jspi、jspi-fetch-streams、jspi-opfs)」均有覆盖,是学习 wasm-bindgen 各能力点的第一手资料。

阅读示例的前置条件

官方文档明确要求读者具备三样工具的知识,若还不熟悉,应先阅读入门教程:

  1. wasm-bindgen:了解#[wasm_bindgen]宏的导入(extern "C")与导出(pub fn)机制;
  2. wasm-pack:了解如何把 Rust 工程打包成 Wasm + JS 胶水代码;
  3. Rust + WebAssembly 项目的构建方式:了解wasm32-unknown-unknown目标与 Cargo 的基本工作流。

如果你对这些还不熟悉,文档建议先完成Game of Life 教程(Rust 官方 RustWasm 书籍)或wasm-pack 官方教程,再回来阅读示例会顺畅得多。

获取与运行所有示例

所有示例的源码都托管在仓库中,可以下载到本地直接运行。文档给出的建议是:测试之前优先切换到最新的 release 版本,以保证示例与已发布 API 的兼容性。

注意:仓库是只读镜像,本文只介绍查看、运行与配置方式,不涉及修改仓库内容。

基于 Webpack 的示例:pnpm run serve

大多数示例都配置了 Webpack +wasm-pack,可以用pnpm run serve一键构建并启动开发服务器。这一工作流在仓库中有明确支撑:

  • 根级 examples/package.json 定义了build(pnpm run -r build)、serve(serve)、pretest(构建 wasm-bindgen CLI)等脚本;
  • examples/pnpm-workspace.yaml 声明packages: - "*",即所有子目录都是 pnpm workspace 成员,并把@wasm-tool/wasm-pack-plugin、webpack、webpack-cli、webpack-dev-server等依赖统一锁定在catalog中。

以 hello_world 示例 为例,其 README 明确写着:

$ npm run serve

然后浏览器访问http://localhost:8080即可看到运行效果。其工程结构正是标准「Webpack + wasm-pack」模式:

  • examples/hello_world/src/lib.rs:用#[wasm_bindgen]导入alert,并导出greet函数;
  • examples/hello_world/index.js:import { greet } from './pkg'后调用;
  • examples/hello_world/webpack.config.js:通过WasmPackPlugin指定crateDirectory: __dirname自动执行 wasm-pack 构建,输出到../dist/hello_world,并开启experiments.asyncWebAssembly。

如果你在仓库根目录执行,对应命令即pnpm run serve(由 examples/package.json 中serve脚本serve提供静态服务)。注意:hello_world 的 README 写成npm run serve是因为它早期使用 npm,当前仓库统一采用 pnpm workspace,实际执行应以仓库根级脚本为准。

不使用 Webpack 的示例:独立构建说明或build.sh

文档特别提到:不是所有示例都用 Webpack。不使用 Webpack 的示例会自带构建说明或build.sh脚本,例如:

  • examples/without-a-bundler:README 给出wasm-pack build --target web的构建命令,然后用任意静态服务器(http、python2 -m SimpleHTTPServer、python3 -m http.server)托管目录后访问index.html;
  • examples/nodejs_and_deno:package.json 中分别提供build:nodejs(--target nodejs)、build:deno(--target deno)、build:experimental-nodejs-module、build:esm-integration等多套构建脚本;
  • examples/synchronous-instantiation:展示不使用 ES 模块的同步实例化方式。

此外,根级 examples/cp-dist.mjs 是一个极简的跨平台拷贝工具,被 without-a-bundler 的 postbuild 等脚本用来把index.html复制进dist目录,这也是非 Webpack 示例常用的发布手段之一。

深入理解:为什么大多数示例用 Webpack(但并非必须)

文档明确指出:大多数示例目前使用 Webpack 来组装最终产物,但这并非强制要求。原因在于wasm-bindgen的默认输出(即--target bundler)把 Wasm 模块视为原生 ES 模块来生成,而目前没有任何 JS 运行时原生实现这一模型,因此默认输出必须借助某种打包器才能消费。这个默认选择是为了顺应 JS 生态的趋势——虽然当下只有 bundler 支持把 Wasm 文件当作原生 ES 模块,但未来各工具大概率都会支持。

目前文档确认的、与wasm-bindgen完全兼容的打包器是webpack。仓库绝大多数示例都使用 webpack,并配以@wasm-tool/wasm-pack-plugin(见 examples/pnpm-workspace.yaml 的 catalog 版本锁定),详细的 webpack 配置可以直接参考 hello_world 的 webpack.config.js:

const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin"); module.exports = { entry: './index.js', output: { path: path.resolve(__dirname, '..', 'dist', 'hello_world'), filename: 'index.js', }, plugins: [ new HtmlWebpackPlugin(), new WasmPackPlugin({ crateDirectory: __dirname }), ], mode: 'development', experiments: { asyncWebAssembly: true } };

部署方案总览:--target决定一切

示例的运行方式与部署方式高度耦合,而部署方法的核心就是wasm-bindgen的--target标志。下表完整列出了 部署指南 中定义的七种目标及其适用场景:

--target值说明
bundler适合在 Webpack 等打包器中加载(默认值)
web可在浏览器中直接加载(ES 模块)
nodejs通过require作为 Node.js CommonJS 模块加载
deno通过 Deno 模块导入加载
no-modules类似web,但更古老,不使用 ES 模块
experimental-nodejs-module通过import作为 Node.js ESM 模块加载
module使用新的 source phase imports 语法获取编译后的 Wasm 模块

--target bundler:默认输出,必须配打包器

默认输出假设「Wasm 模块本身是原生 ES 模块」,但该模型尚未在任何 JS 实现中原生支持,所以必须使用打包器消费。目前唯一被确认完全兼容的打包器是 webpack,examples 中绝大多数示例(如 hello_world)都采用此方案。

--target web与--target no-modules:无打包器,浏览器直跑

如果你不使用打包器但仍在浏览器中运行,使用--target web,其要点是:

  • 编译时向wasm-bindgen传--target web;
  • 输出可原生包含在网页中,无需任何后处理,以 ES 模块形式引入;
  • web模式无法使用 NPM 依赖;
  • 需要查阅 浏览器支持要求,因为不会有任何 polyfill 可用。

对应的完整示例见 without-a-bundler 示例,构建命令为wasm-pack build --target web,之后用静态服务器托管即可。

--target no-modules与web类似,同样要求手动初始化 wasm、可直接嵌入网页且无需后处理,但不使用 ES 模块,属于较老的目标,示例同样参考 without-a-bundler。

--target nodejs与--target experimental-nodejs-module:Node.js 部署

  • --target nodejs:将 Wasm 部署进 Node.js(可作为原生模块的替代)。与「无打包器」方案一样无需任何后处理,生成的 JS shim 可以像普通 Node 模块一样被require——甚至*_bg的 Wasm 文件也有对应的 JS shim,可以直接require。要求 Node.js 8 及以上(具备 WebAssembly 支持)。
  • --target experimental-nodejs-module:以 ES 模块方式部署进 Node.js,生成的 shim 可像普通模块一样import。要求 Node.js 12 及以上(具备 WebAssembly 与模块支持)。当前仍处于实验阶段,正式稳定前目标名可能变更。

仓库中 nodejs_and_deno 示例 的build:nodejs与build:experimental-nodejs-module脚本正是这两种目标的具体落地方案;此外还有面向 Node.js 多线程的 nodejs-threads 示例(提供test.js与test-esm.mjs两类测试)。

--target deno:Deno 部署

对 Deno 部署使用--target deno,然后在 Deno 中导入模块:

// @deno-types="./out/crate_name.d.ts" import { yourFunction } from "./out/crate_name.js";

@deno-types注释让 Deno 使用生成的.d.ts类型声明。仓库 nodejs_and_deno 示例 的build:deno脚本(wasm-pack build --target deno)与之对应,其test.js通过deno run --allow-read test.js deno验证 Deno 下的运行。

--target module:source phase imports(跨工具链 ES 模块目标)

这是较新的目标,默认使用source phase imports 语法获取未实例化的 WebAssembly 模块。source phase imports 允许借助 Wasm ESM Integration,导入「编译后的 Wasm 模块(而非其实例)」:

import source wasmModule from "./module.wasm"; // 示例性用法: const instance = new WebAssembly.Instance(wasmModule, imports); export function foo () { instance.doFoo(); }

该方案取代了此前需要compileStreaming以及各平台各自实现的 Wasm 加载路径。部署指南同时注明:source phase imports 目前仅 ESBuild 和 Node.js 24 支持,使用时务必确认运行环境版本满足要求。

发布到 NPM:交给wasm-pack

如果你想把编译好的 WebAssembly 发布到 NPM,文档推荐的工具是wasm-pack,其配套书籍提供了详细流程。

实战路线图:从示例到自己的工程

综合文档与仓库内容,一条完整的上手路径是:

  1. 挑选示例:在 examples 目录中按场景挑选(hello_world入门、dom/canvas/webgl看 Web API、nodejs_and_deno看多目标部署、raytrace-parallel看 Worker 并行、jspi看 JSPI 新特性);
  2. 阅读示例 README:每个示例自带说明(如 hello_world 的 README),先看它的构建命令与访问方式;
  3. 构建运行:Webpack 类示例在仓库根目录执行pnpm run serve;非 Webpack 类示例按各自 README 或 package.json 脚本(如wasm-pack build --target web)构建,再用静态服务器托管;
  4. 理解输出目标:结合 部署指南 的--target表格判断产物适合 bundler / 浏览器 / Node.js / Deno 中的哪种环境;
  5. 对照源码修改:例如把 hello_world/src/lib.rs 的greet换成自己的函数,或把 without-a-bundler 的--target web换成--target nodejs,观察胶水代码差异——这正是理解 wasm-bindgen 桥接机制最直接的方式。

延伸阅读

  • 官方示例文档入口:guide/src/examples/index.md
  • 全部示例源码:examples/
  • 部署与集成指南:guide/src/reference/deployment.md
  • 浏览器兼容性要求:guide/src/reference/browser-support.md
  • 开发工具

【免费下载链接】wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript

项目地址:https://gitcode.com/gh_mirrors/wa/wasm-bindgen
点击查看免费下载
上一篇:PyTorch-FCN数据集完全攻略:VOC、NYUD、SIFT Flow实战教程
下一篇:为什么选择lazymc?6大优势让你的Minecraft服务器更高效

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询