
开发工具【免费下载链接】wasm-bindgenFacilitating high-level interactions between Wasm modules and JavaScript项目地址https://gitcode.com/gh_mirrors/wa/wasm-bindgen点击查看免费下载导读web-sys是 wasm-bindgen 生态中面向 Web 平台的原始绑定库它为几乎所有浏览器 Web APIDOM、WebGL、WebAudio、WebGPU、WebRTC、IndexedDB 等提供了 Rust 侧的#[wasm_bindgen]导入。本文以 crates/web-sys/README.md 为主线完整讲解 web-sys 的定位、以Cargo Feature 逐个门控 API为核心的设计哲学以及当你需要使用的 Web API 尚未被收录时如何利用wasm-bindgen-webidl生成器把 WebIDL 变成 Rust 绑定的六步流程。读完本文你将掌握 web-sys 的依赖配置、Feature 启用规则、继承层次的访问方式以及从 WebIDL 到生成代码的底层运作原理。一、web-sys 是什么面向 wasm-bindgen 的 Web API 原始绑定web-sys的定位在 crates/web-sys/README.md 开头一句话即可概括Raw bindings to Web APIs for projects usingwasm-bindgen为使用 wasm-bindgen 的项目提供 Web API 的原始绑定。它覆盖的 API 范围非常广包括但不限于window.fetchNode.prototype.appendChildWebGLWebAudio以及更多浏览器标准 API社区常常用一句话类比它的地位web-sys 之于 Web就像libc之于操作系统——它是一层尽可能完整、贴近底层的系统级绑定不掺杂高层次的封装逻辑。需要特别区分的是web-sys不包含ECMAScript 标准环境中必然存在的那部分 JavaScript API例如Array、Date、eval。这些与具体宿主环境无关的 JS 内置对象绑定由同仓库的js-syscrate 提供见 guide/src/web-sys/index.md 与 crates/js-sys/。也就是说js-sys标准 ECMAScript 环境的内置对象Array、Date、Promise、JSON…与浏览器无关web-sys浏览器/Web 平台独有 APIDOM、媒体、图形、网络、传感器…依赖 js-sys 作为基础类型层。两者在依赖上也是分层关系crates/web-sys/Cargo.toml 中web-sys以default-features false的方式依赖js-sys与wasm-bindgen并通过stdFeature 向上传递wasm-bindgen/std与js-sys/std。二、Cargo Feature 门控每个类型一个 Feature2.1 设计规则默认几乎为空web-sys 最核心的设计约束是编译速度它暴露的 API 数量极其庞大如果全部编译构建时间将难以接受。因此 crates/web-sys/README.md 明确说明This crate by default contains very little when compiled as almost all of its exposed APIs are gated by Cargo features.默认情况下 web-sys 几乎不包含任何内容所有公开 API 都被 Cargo Feature 门控。规则非常简单直接规则之拇指每个类型拥有一个以自己名字命名的 Feature使用某个 API需要同时启用该 API 涉及的全部类型的 Feature每个 API 的文档都会注明它依赖哪些 Feature。从 crates/web-sys/Cargo.toml 的[features]段可以看到这一规则的具体形态。例如default [std] std [wasm-bindgen/std, js-sys/std] AbortController [] AbortSignal [EventTarget] Event [] EventTarget [] Window [EventTarget] WebSocket [EventTarget] Document [EventTarget, Node] Element [EventTarget, Node] HtmlAnchorElement [Element, EventTarget, HtmlElement, Node] Node [EventTarget]2.2 Feature 之间的依赖传递上例中AbortSignal [EventTarget]这种写法揭示了 web-sys 的 Feature 依赖模型一个类型的 Feature 会自动传递启用其**父类型继承链上的祖先**的 Feature。这在 guide/src/web-sys/cargo-features.md 中有专门阐述要访问某个类型必须启用它的 Feature要访问某个方法必须启用其self类型的 Feature以及每个参数类型的 Feature。以文档中的经典例子WebGlRenderingContext::compile_shader为例它要求WebGlRenderingContext因为它是该方法的self类型WebGlShader因为该方法接收一个WebGlShader参数。因此Feature 列表并非孤立存在而是形成一张依赖图启用一个叶子类型的 Feature 时其继承链上所有祖先类型的 Feature 都会被连带启用从而保证Deref到父类后调用父类方法时类型依然可用。这正是 crates/web-sys/Cargo.toml 中大量条目携带方括号依赖如HtmlDivElement [Element, EventTarget, HtmlElement, Node]、AnalyserNode [AudioNode, EventTarget]的原因。2.3 从源码看 Feature 的生成与维护需要强调的是这份动辄数百行的 Feature 列表不是手写的。crates/web-sys/Cargo.toml 在[features]段上方有一行注释# This list is auto-generated by the wasm-bindgen-webidl program即该列表由wasm-bindgen-webidl程序自动生成。查看 crates/webidl/src/main.rs 可知wasm-bindgen-webidl的入口接收input_dirWebIDL 输入目录与output_dir生成的 Rust 代码输出目录可选地接收cargo_toml_path在生成绑定代码之后调用update_cargo_toml_features把新接口的 Feature 写回 Cargo.toml。另外它还支持两个 CLI 开关--no-features生成时不产出 Feature 门控同时跳过 Cargo.toml 的更新--next-unstable配合下一节介绍的不稳定 API 机制使用。三、快速上手三步接入 web-sys第一步添加依赖在Cargo.toml中声明web-sys依赖完整示例见 guide/src/web-sys/using-web-sys.md[dependencies] wasm-bindgen 0.2 [dependencies.web-sys] version 0.3 features [ ]第二步按需启用 Feature因为 Feature 门控机制的存在Feature 列表通常是空的起步状态随后按你实际用到的 API 逐个补充。查找方式是在 API 文档中定位你要用的类型或方法文档会列出其必需的 Feature。例如要使用window.resizeTo即 Rust 侧的web_sys::Window::resize_to需要启用WindowFeature[dependencies.web-sys] version 0.3 features [ Window ]第三步调用方法use wasm_bindgen::prelude::*; use web_sys::Window; #[wasm_bindgen] pub fn make_the_window_small() { // Resize the window to 500px by 500px. let window web_sys::window().unwrap(); window.resize_to(500, 500) .expect(could not resize the window); }注意resize_to返回Result——这正是 crates/web-sys/README.md 中对可能抛错的函数标注[Throws]这一约定在生成代码层面的体现WebIDL 中标了[Throws]的接口生成的 Rust 方法会返回Result调用方必须处理可能的 JS 异常。四、使用继承层次Deref、AsRef 与 JsCastDOM 的核心工作方式就是 JS 类之间的继承web-sys 通过三种方式把这一层次暴露给 Rust 开发者详见 guide/src/web-sys/inheritance.md。4.1 用Deref向上访问父类与 Rust 智能指针类似web-sys 中所有类型都对其父 JS 类实现Deref。因此拿到一个web_sys::Element就能隐式地把它当web_sys::Node使用let element: Element ...; element.append_child(..); // 调用 Node 上的方法 method_expecting_a_node(element); // 隐式协变到 Node let node: Node element; // 显式协变到 Node借助Deref你可以顺着继承链一路向上用.运算符直接访问祖先类的所有方法。4.2 用AsRef显式取父类引用除Deref外web-sys 为继承链上每一层祖先都实现了AsRef。以HtmlAnchorElement为例guide/src/web-sys/inheritance.mdimpl AsRefHtmlElement for HtmlAnchorElement impl AsRefElement for HtmlAnchorElement impl AsRefNode for HtmlAnchorElement impl AsRefEventTarget for HtmlAnchorElement impl AsRefObject for HtmlAnchorElement impl AsRefJsValue for HtmlAnchorElement可以用.as_ref()显式取得任一父类的引用由于实现数量多调用时通常需要类型推断来指明目标类型。4.3 用JsCast向下转型wasm_bindgen::JsCasttrait 则负责各种类型之间的转换既支持静态的无检查转换也支持基于instanceof的运行时动态检查转换。这在把通用类型如EventTarget向下转成具体类型如HtmlInputElement时至关重要。五、扩展 web-sys把新 Web API 添加进来的完整流程这是 crates/web-sys/README.md 的核心实操章节。当你在 web-sys 中找不到某个 Web API 时可以按以下六步把它加入。步骤 1获取 WebIDL 并放入 unstable 目录把该 API 的 WebIDL 规范复制到一个新文件放入webidls/unstable文件夹。如何找到 WebIDL以 MediaSession API 为例打开 MDN 对应文档页滚动到底部点击 Specifications 链接进入规范页再滚动到规范页的最底部即可看到完整的 IDLIDL Index。在仓库中crates/web-sys/webidls/unstable/ 目录下已经放着大量此类文件例如MediaSession.webidlWebGPU.webidlWebXRDevice.webidl、WebXRHandInputModule.webidl、WebXRGamepadsModule.webidlWebTransport.webidlWebSerial.webidl、WebUSB.webidl、WebHID.webidl、Bluetooth.webidlFileSystemAccess.webidl、Clipboard.webidl、PictureInPicture.webidl、WebCodecs.webidl同一目录下还划分了enabled/、disabled/、unavailable_option_primitive/等子目录从目录结构看unstable/用于存放规范仍在演进、尚未正式定稿的接口 IDL详见下一节不稳定 API。步骤 2用[Throws]标注可抛错的函数对规范中可能抛出异常的函数在 WebIDL 中为其加上[Throws]注解。生成器读到该注解后会把对应方法生成为返回Result的 Rust 函数从而把 JS 异常安全地映射进 Rust 的错误处理流程。步骤 3进入 crate 目录cd crates/web-sys步骤 4运行生成器命令cargo run --release --package wasm-bindgen-webidl -- webidls src/features ./Cargo.toml这条命令拆解如下参数含义--package wasm-bindgen-webidl指定要运行的 Cargo 包即 crates/webidl 下的二进制程序webidls第一个位置参数即 WebIDL 输入目录crates/web-sys/webidlssrc/features第二个位置参数即生成的 Rust 绑定代码输出目录./Cargo.toml第三个位置参数生成器会把新增接口对应的 Feature 自动写回该文件对照 crates/webidl/src/main.rs该命令执行的核心逻辑是generate()解析webidls/下所有 WebIDL 文件产出带#[cfg(feature …)]门控的 Rust 绑定到src/features/随后update_cargo_toml_features()将新生成的 Feature含依赖传递关系追加进Cargo.toml的[features]段。README 明确提示此列表由wasm-bindgen-webidl自动生成因此不要手改Feature 列表。步骤 5暂存生成的文件git add .把所有生成文件包括src/features/下的新绑定代码与更新后的Cargo.toml加入版本控制。步骤 6更新 CHANGELOG在 crates/web-sys/CHANGELOG.md 中按如下格式添加条目PR 编号处填写你提交的 pull request 链接... ## Unreleased ### Added ... * Added your addition [#1234](https://github.com/wasm-bindgen/wasm-bindgen/pull/1234) # - link to your PR测试佐证新接口落地后仓库内已有大量针对生成绑定的 wasm 测试可供参考例如 crates/web-sys/tests/wasm/element.rs 中通过#[wasm_bindgen_test]直接调用Element的prefix()、local_name()、tag_name()、set_attribute()、toggle_attribute()等方法并断言结果验证了绑定代码在真实浏览器/Node wasm 环境下的行为crates/web-sys/tests/wasm/下还有blob.rs、console.rs、indexeddb.rs、history.rs、opfs.rs等覆盖各 API 域的测试文件是评估一个接口绑定是否完整可用的现成样板。六、不稳定 APIweb_sys_unstable_apis开关浏览器常常在规范尚未定稿时就先行实现部分 API这类接口的 WebIDL 会随规范频繁变动。若 web-sys 直接按当前草案生成并发布一旦草案修改已发布的版本就失效了而且 web-sys 会被迫频繁做出破坏性变更。解决方案详见 guide/src/web-sys/unstable-apis.md是把所有不稳定 API 用如下属性隐藏起来#[cfg(web_sys_unstable_apis)] pub struct Foo;这样使用方必须**显式选择接受较低稳定性保证**才能看到这些 API作为代价这些 API不遵循 semverWebIDL 一变化就可能被破坏。启用方式有两种通过RUSTFLAGS环境变量推荐最直接RUSTFLAGS--cfgweb_sys_unstable_apis cargo run通过 Cargo 配置文件./.cargo/config.toml[build] rustflags [--cfgweb_sys_unstable_apis]对应地crates/web-sys/Cargo.toml 在发布文档配置中也启用了该 cfgrustdoc-args [--cfgweb_sys_unstable_apis]、all-features true并在[lints.rust]中通过unexpected_cfgs的check-cfg声明了这一合法 cfg 标志前述生成器命令的--next-unstable参数也与此机制配套。七、生成管线的源码级透视把 README 中的流程与仓库源码对照可以更完整地理解 web-sys 的生产线输入WebIDL 规范文件存放在 crates/web-sys/webidls/enabled/、disabled/、unstable/等子目录按接口的稳定性/可用性分类处理crates/webidl/src 下的first_pass.rs首遍解析、traverse.rs遍历 IDL 树、generator.rs生成 Rust 代码、update_cargo_toml.rs回写 Feature共同完成从 WebIDL 到#[wasm_bindgen]绑定代码的转换输出生成结果写入crates/web-sys/src/features/Feature 列表自动同步进 crates/web-sys/Cargo.toml并连带生成[Throws]→Result、继承链→Deref/AsRef、接口→独立 Feature 等约定产物。也就是说web-sys 约 700 余个 Feature从AbortController一直到console、gpu_texture_usage等覆盖 DOM、HTML 元素、SVG、WebGL、WebGPU、WebRTC、IndexedDB、传感器、XR 等领域的最终形态完全由这套 WebIDL→代码的自动化管线驱动README 的六步流程正是这条管线的人工操作手册。总结定位web-sys 是 wasm-bindgen 的 Web API 原始绑定层覆盖面对标浏览器全部标准接口不含 ECMAScript 内置对象后者归 js-sys门控哲学默认零内容每个类型一个 Cargo Feature方法可用性取决于self类型与参数类型的 Feature 集合祖先类型 Feature 自动传递上手路径Cargo.toml加依赖 → 按 API 文档启用所需 Feature →#[wasm_bindgen]函数中直接调用扩展路径获取 WebIDL 放入 crates/web-sys/webidls/unstable/ → 标注[Throws]→ 运行cargo run --release --package wasm-bindgen-webidl -- webidls src/features ./Cargo.toml→git add .→ 更新 CHANGELOG.md稳定性边界不成熟接口由web_sys_unstable_apiscfg 隐藏启用即放弃 semver 保证。对 Web 平台 API 有完整、无封装、可直接编译为 wasm 的 Rust 绑定需求时web-sys 是 wasm-bindgen 项目中最直接的答案而当需求超出已收录范围README 给出的六步流程则让每个开发者都能把缺失的接口补进这条自动化的 WebIDL 生成管线。赞分享开发工具【免费下载链接】wasm-bindgenFacilitating high-level interactions between Wasm modules and JavaScript项目地址https://gitcode.com/gh_mirrors/wa/wasm-bindgen点击查看免费下载相关推荐深入解析 wasm-bindgen 的 web-sys crateWebIDL 驱动的 Web API 绑定生成与 Cargo feature 机制深入解析 wasm bindgen 的 web sys crateWebIDL 驱动的 Web API 绑定生成与 Cargo feature 机制 web开发工具wasm-bindgen 之 web-sys可选原始类型参数optional primitive为何无法构建绑定wasm bindgen 之 web sys可选原始类型参数optional primitive为何无法构建绑定 导读 在 web sys 中可选原始开发工具为 web-sys 扩展新的 Web API从 WebIDL 到 Rust 绑定的完整贡献指南为 web sys 扩展新的 Web API从 WebIDL 到 Rust 绑定的完整贡献指南 web sys 是 wasm bindgen 生态中面向 We开发工具上一篇Iwara视频下载终极指南如何轻松批量下载你喜欢的视频下一篇DeepChat 离线 Light OCR 附件路由:从附件准备到打包校验的完整实现解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考