#web-api #javascript #asmjs

未维护 stdweb

客户端Web的标准库

30次发布

使用旧的Rust 2015

0.4.20 2019年10月10日
0.4.18 2019年7月15日
0.4.15 2019年3月13日
0.4.12 2018年12月15日
0.0.0 2017年3月12日

#9 in #asmjs

Download history 34258/week @ 2024-03-14 31302/week @ 2024-03-21 45621/week @ 2024-03-28 37598/week @ 2024-04-04 35049/week @ 2024-04-11 38549/week @ 2024-04-18 33046/week @ 2024-04-25 34996/week @ 2024-05-02 35149/week @ 2024-05-09 58137/week @ 2024-05-16 50530/week @ 2024-05-23 45703/week @ 2024-05-30 42210/week @ 2024-06-06 43623/week @ 2024-06-13 40127/week @ 2024-06-20 30765/week @ 2024-06-27

165,833 每月下载
用于 少于 60 crates

MIT/Apache

1MB
16K SLoC

Build Status Join the chat at https://gitter.im/stdweb-rs/stdweb

客户端Web的标准库

Documentation

此crate的目标是提供对Web API的Rust绑定,并允许Rust和JavaScript之间有高度互操作性。

捐赠

Become a patron

赞助商

感谢这些可爱的人带来了这款软件

  • Embark Studios
  • Joe Narvaez
  • Eduard Knyshov
  • Anselm Eickhoff
  • Johan Andersson
  • Stephen Sugden
  • is8ac

谢谢!

示例

您可以直接将JavaScript代码嵌入到Rust中

let message = "Hello, 世界!";
let result = js! {
    alert( @{message} );
    return 2 + 2 * 2;
};

println!( "2 + 2 * 2 = {:?}", result );

闭包也受支持

let print_hello = |name: String| {
    println!( "Hello, {}!", name );
};

js! {
    var print_hello = @{print_hello};
    print_hello( "Bob" );
    print_hello.drop(); // Necessary to clean up the closure on Rust's side.
}

您还可以通过serde传递任意结构

#[derive(Serialize)]
struct Person {
    name: String,
    age: i32
}

js_serializable!( Person );

js! {
    var person = @{person};
    console.log( person.name + " is " + person.age + " years old." );
};

此crate还公开了一些Web API,例如

let button = document().query_selector( "#hide-button" ).unwrap().unwrap();
button.add_event_listener( move |_: ClickEvent| {
    for anchor in document().query_selector_all( "#main a" ) {
        js!( @{anchor}.style = "display: none;"; );
    }
});

也支持将Rust函数公开给JavaScript

#[js_export]
fn hash( string: String ) -> String {
    let mut hasher = Sha1::new();
    hasher.update( string.as_bytes() );
    hasher.digest().to_string()
}

然后您可以从Node.js这样做

var hasher = require( "hasher.js" ); // Where `hasher.js` is generated from Rust code.
console.log( hasher.hash( "Hello world!" ) );

或者您可以将相同的.js文件用于Web浏览器

<script src="hasher.js"></script>
<script>
    Rust.hasher.then( function( hasher ) {
        console.log( hasher.hash( "Hello world!" ) );
    });
</script>

如果您使用Parcel,您还可以使用我们的实验性Parcel插件;首先在您的现有Parcel项目中这样做

$ npm install --save parcel-plugin-cargo-web

然后简单地进行以下操作

import hasher from "./hasher/Cargo.toml";
console.log( hasher.hash( "Hello world!" ) );

设计目标

  • 公开由网络浏览器公开的完整套件Web API。
  • 尽可能地遵循原始JavaScript约定和结构,除非这样做会导致明显更好的设计。
  • 成为构建块,从中可以构建更高级的框架和库。
  • 使其方便并易于将JavaScript代码直接嵌入到Rust中,并在两者之间传输数据。
  • 与更广泛的Rust生态系统集成,例如支持实现serde的Serializable的结构的传输。
  • 将Rust置于驾驶员座位上,在不需要触摸JavaScript的情况下编写非平凡的网络应用程序。
  • 允许Rust参与即将到来的WebAssembly(再次)革命。
  • 使其能够轻松创建可以从JavaScript轻松调用的独立库。

入门

查看一些示例

  • examples/minimal - 一个完全最小的示例,调用alert
  • examples/todomvc - 一个原始实现的TodoMVC应用程序;显示如何调用DOM
  • examples/hasher - 展示如何将 Rust 函数导出到 JavaScript,以及如何在纯网页浏览器环境或 Nodejs 中调用它们
  • examples/hasher-parcel - 展示如何在 Parcel 项目中导入和调用导出的 Rust 函数
  • pinky-web - 一个 NES 模拟器;您可以在这里使用预编译版本进行游戏

API 文档也供您参考。

运行示例

  1. 安装 cargo-web

    $ cargo install -f cargo-web
    
  2. 进入 examples/todomvc 目录,并使用以下命令之一启动示例

    • 使用 Rust 的原生 WebAssembly 后端编译为 WebAssembly

      $ cargo web start --target=wasm32-unknown-unknown
      
    • 使用 Emscripten 编译为 asm.js

      $ cargo web start --target=asmjs-unknown-emscripten
      
    • 使用 Emscripten 编译为 WebAssembly

      $ cargo web start --target=wasm32-unknown-emscripten
      
  3. 使用您的浏览器访问 https://127.0.0.1:8000

对于 *-emscripten 目标,不需要 cargo-web,但是需要 cargo-web 才能使用不需要 Emscripten 的本地 wasm32-unknown-unknown

更新日志

  • stdweb0.4.20

    • 与最新版 wasm-bindgen 的兼容性
    • 新事件
      • FullscreenChangeEvent
  • stdweb0.4.19

    • 新方法
      • Document::fullscreen_enabled
      • Document::fullscreen_element
      • InputElement::selection_start
      • InputElement::selection_end
      • InputElement::set_selection_start
      • InputElement::set_selection_end
      • Object::to_iter
      • Window::confirm
    • &Array 现在可以通过 TryFrom 转换为 Vec
    • 运行时现在应与 Emscripten 的新版本兼容
    • 与不稳定 futures 相关的 API 已更新,以与最新的夜版本兼容
    • syn 依赖项已更新到版本 1
  • stdweb0.4.18

    • js! 宏现在可以通过 use 导入
    • 新事件
      • BeforeUnloadEvent
      • UnloadEvent
    • 新方法
      • IBlob::slice
      • IBlob::slice_with_content_type
      • IWindowOrWorker::set_clearable_timeout
  • stdweb0.4.17

    • 与不稳定 futures 相关的 API 已更新,以与最新的夜版本兼容
  • stdweb0.4.16

    • 初始 wasm-bindgen 兼容性;现在您可以在使用 wasm-bindgen 的项目中使用 stdweb
    • 最低支持的 Rust 版本是 1.33.0
    • 最低要求的 cargo-web 版本是 0.6.24
  • stdweb0.4.15

    • 与不稳定 futures 相关的 API 已更新,以与最新的夜版本兼容
    • 新类型
      • FormData
      • FormDataEntry
      • MouseButtonsState
    • 新方法
      • Blob::new
  • stdweb0.4.14

    • 如果您的 JS 片段不返回任何内容,则 js! 宏现在会生成更高效的代码。这使您在大多数情况下不需要添加 @(no_return) 注释。
    • 新类型
      • File
  • stdweb0.4.13

    • 修复了过程化 js! 宏的空白处理
    • 新类型
      • ITouchEvent
      • Touch
      • TouchType
    • 新事件
      • TouchEvent
      • TouchMove
      • TouchLeave
      • TouchEnter
      • TouchEnd
      • TouchCancel
      • TouchStart
    • 新方法
      • XmlHttpRequest::set_response_type
  • stdweb0.4.12

    • 改进了在无需 cargo-web 的情况下尝试编译为 wasm32-unknown-unknown 目标时的诊断
  • stdweb0.4.11

    • 最低要求的 Rust 版本是 1.30.1
    • 最低要求的 cargo-web 版本是 0.6.22
    • wasm32-unknown-unknown 现在在稳定版 Rust 中官方支持
    • 现在支持在 wasm32-unknown-unknown 上进行调试构建
    • js! 宏现在部分使用过程宏实现
    • 由于使用了本地编解码器API,字符串解码/编码现在快得多
    • 新方法
      • Document::import_node
      • IElement::slot
      • IElement::attach_shadow
      • IElement::shadow_root
    • 新类型
      • ISlotable
      • ShadowRoot
      • ShadowRootMode
      • TemplateElement
      • SlotElement
    • 新事件
      • SlotChangeEvent
    • IParentNode::query_selectorIParentNode::query_selector_all 现在返回正确的错误类型
  • stdweb 0.4.10stdweb-derive 0.5.1

    • 新方法
      • IElement::insert_adjacent_html
      • IElement::insert_html_before
      • IElement::insert_html_after
      • IElement::prepend_html
      • IElement::append_html
      • IElement::namespace_uri
      • IElement::closest
      • Document::create_element_ns
      • Window::get_selection
    • 新类型
      • AbortError
      • SelectionType
      • Selection
      • Range
    • 失败的类型转换的错误信息现在得到了改进
    • 失败的转换的错误类型(当使用 .try_into()/.try_from())现在可以转换为 TypeError
    • 聚合错误类型(如 DrawImageError)现在可以通过 js! 宏进行序列化
    • TypeError 现在已修复(它被错误地处理为 DOMException
    • Number 现在可以通过 .into()/.from() 转换为 f64
    • 添加了 Mut,它是一个新的包装类型,用于安全地将 FnMut 闭包传递给 js! 宏;目前它是可选的,但是这个包装类型的用法将来将是强制性的!
    • FnMut 闭包不能再递归调用了
    • #[derive)] 现在支持有限的一组泛型类型
    • 现在支持异步单元测试,使用新的 #[async_test] 属性宏(仅限nightly版)
    • 更新到 futures 0.3(仅限nightly版)
  • stdweb 0.4.9stdweb-derive 0.5.0

    • 性能改进;通过 serde 进行序列化现在快两倍
    • 新事件
      • ScrollEvent
      • DragRelatedEvent
      • DragEvent
      • DragStartEvent
      • DragEndEvent
      • DragEnterEvent
      • DragLeaveEvent
      • DragOverEvent
      • DragExitEvent
      • DragDropEvent
    • 新类型
      • DataTransfer
      • EffectAllowed
      • DropEffect
      • DataTransferItemList
      • DataTransferItem
      • DataTransferItemKind
      • IDragEvent
    • Value现在可以使用try_into转换为Option< Serde< T > >
    • 通过serde反序列化数字现在在大多数情况下都可行,允许使用除了i32f64之外的其他类型
    • 所有事件现在都具有更强的类型
      • 之前可以将例如keyup事件反序列化为KeyDownEvent,因为只检查了事件的JS类型,并且keyupkeydown共享相同的JS类型(KeyboardEvent)。从现在开始,也会检查事件的type字段,因此不再允许这种转换。
  • 0.4.8

    • 针对wasm32-unknown-unknown目标时在最新夜间的编译问题已修复
    • 新事件
      • PointerLockChangeEvent
      • PointerLockErrorEvent
      • MouseWheelEvent
    • 新类型
      • MouseWheelDeltaMode
      • XhrResponseType
    • 新方法
      • XmlHttpRequest::raw_response
      • Window::device_pixel_ratio
      • Document::pointer_lock_element
      • Document::exit_pointer_lock
  • 0.4.7

    • 新事件
      • AuxClickEvent
      • MouseEnterEvent
      • MouseLeaveEvent
      • ContextMenuEvent
      • SelectionChangeEvent
    • 新类型
      • FileList
      • FileReaderReadyState
    • 实现游戏手柄API
      • Gamepad
      • GamepadButton
      • GamepadButtonMapping
      • GamepadEvent
    • 修复了CanvasRenderingContext2d::clear_rect的编译问题
    • 修复了从VecArrayBuffer创建TypedArray时的泄漏问题。
  • 0.4.6

    • 再次修复docs.rs
    • 新类型
      • SubmitEvent
      • IChildNode
    • 修复了CanvasElement::to_data_url
  • 0.4.5

    • 新类型
      • DocumentFragment
      • SelectElement
      • OptionElement
      • HtmlCollection
    • 新方法
      • Node::from_html
      • Value::is_null
    • 暴露枚举
      • SocketMessageData
      • NodeType
    • 更新到futures 0.2
  • 0.4.4

    • 修复docs.rs(希望如此)。
    • 新方法
      • Location::origin
      • Location::protocol
      • Location::host
      • Location::hostname
      • Location::port
      • Location::pathname
      • Location::search
    • 这些现在在错误情况下返回SecurityError
      • Location::hash
      • Location::href
  • 0.4.3

    • 现在应支持不能用作WeakMap键的对象(例如Firefox下的一些WebGL相关对象)
    • 新方法
      • Element::get_bounding_client_rect
      • Element::scroll_top
      • Element::scroll_left
      • Window::page_x_offset
      • Window::page_y_offset
      • NodeList::item
      • Document::body
      • Document::head
      • Document::title
      • Document::set_title
      • IMouseEvent::offset_x
      • IMouseEvent::offset_y
    • 暴露更多与canvas相关的类型
      • CompositeOperation
      • LineCap
      • LineJoin
      • Repetition
      • TextAlign
      • TextBaseline
    • 暴露与canvas相关的错误类型:AddColorStopErrorDrawImageErrorGetImageDataError
    • 新事件
      • MouseOverEvent
      • MouseOutEvent
      • PointerOverEvent
      • PointerEnterEvent
      • PointerDownEvent
      • PointerMoveEvent
      • PointerUpEvent
      • PointerCancelEvent
      • PointerOutEvent
      • PointerLeaveEvent
      • GotPointerCaptureEvent
      • LostPointerCaptureEvent
    • 新的指针事件接口:IPointerEvent
  • 0.4.2

    • 修复了解析引用时的泄漏问题
    • 修复了CanvasRenderingContext2d::get_canvas
    • 暴露了FillRuleSocketReadyState
    • IElement中添加了新的属性相关方法
    • 添加了新的Date绑定
  • 0.4.1

    • 支持最新的夜间版Rust在wasm32-unknown-unknown
    • 公开了SocketBinaryType枚举
    • 添加了新的画布API
      • CanvasRenderingContext2d添加了许多新方法
      • 新类型:CanvasGradientCanvasPatternCanvasStyleImageDataTextMetrics
    • 添加了新的错误类型:IndexSizeErrorNotSupportedErrorTypeError
  • 0.4

    • (破坏性变更) 从Value中删除了ArrayObject变体;现在它们被视为Reference
    • (破坏性变更) Value有一个额外的变体:Symbol
    • (破坏性变更) 删除了
      • InputElement::set_kind
      • InputElement::files
    • (破坏性变更) 重命名
      • KeydownEvent -> KeyDownEvent
      • KeyupEvent -> KeyUpEvent
      • KeypressEvent -> KeyPressEvent
      • ReadyState -> FileReaderReadyState
      • InputElement::value -> InputElement::raw_value
      • InputElement::set_value -> InputElement::set_raw_value
    • (破坏性变更) ArrayBuffer::new现在接受一个u64参数
    • (破坏性变更) InputElement::set_raw_value现在接受&str而不是Into< Value >
    • (破坏性变更) 修改了返回类型
      • 所有返回usize的方法现在返回u32
      • INode::remove_child现在在Ok情况下返回Node
      • 以下现在返回一个u64
        • ArrayBuffer::len
      • 以下现在返回一个i32而不是f64
        • IMouseEvent::client_x
        • IMouseEvent::client_y
        • IMouseEvent::movement_x
        • IMouseEvent::movement_y
        • IMouseEvent::screen_x
        • IMouseEvent::screen_y
      • 以下现在返回一个Result
        • INode::insert_before
        • INode::replace_child
        • INode::clone_node
        • StringMap::insert
        • TokenList::add
        • TokenList::remove
        • Document::create_element
        • IEventTarget::dispatch_event
        • FileReader::read_as_text
        • FileReader::read_as_array_buffer
        • FileReader::read_as_text
        • History::replace_state
        • History::go
        • History::back
        • History::forward
        • Location::href
        • Location::hash
        • CanvasElement::to_data_url
        • CanvasElement::to_blob
        • ArrayBuffer::new
      • INode::base_uri现在返回一个String而不是Option< String >
      • InputElement::raw_value现在返回一个String而不是Value
    • (重大变更) INode::inner_text 已移动到 IHtmlElement::inner_text
    • (重大变更) Document::query_selectorDocument::query_selector_all 已移动到 IParentNode
    • (重大变更) IElement::query_selectorIElement::query_selector_all 已移动到 IParentNode
    • (重大变更) Document::get_element_by_id 已移动到 INonElementParentNode
    • (重大变更) 使用 TryFrom/TryInto 在任意引用类似对象之间进行转换的通用实现已被移除
    • 当使用最新的 cargo-web 构建时,不再需要调用 stdweb::initializestdweb::event_loop
    • wasm32-unknown-unknown 上支持 cdylib 链接库
    • 新绑定
      • XmlHttpRequest
      • WebSocket
      • MutationObserver
      • History
      • TextAreaElement
      • CanvasElement
    • 新事件类型
      • MouseDownEvent
      • MouseUpEvent
      • MouseMoveEvent
      • PopStateEvent
      • ResizeEvent
      • ReadyStateChange
      • SocketCloseEvent
      • SocketErrorEvent
      • SocketOpenEvent
      • SocketMessageEvent
    • 对 Canvas APIs 的初步支持
    • 新特性: ReferenceTypeInstanceOf
    • stdweb-derive 链接库中添加 #[derive(ReferenceType)] 注解;现在可以在 stdweb 之外定义自定义 API 绑定
    • 添加 #[js_export] 过程式属性(仅限 wasm32-unknown-unknown
    • 添加 DomException 和其子类型,用于传递 JavaScript 异常
    • IElement 现在继承自 INode
    • 每个接口现在都继承自 ReferenceType
    • 添加 stdweb::traits 模块,用作使用所有接口特性的预言
    • 添加 console!
    • 大多数类型现在实现了 PartialEqEq
  • 0.3

    • (重大变更) 删除了 ErrorEvent 方法
    • (破坏性变更) 重命名
      • LoadEvent -> ResourceLoadEvent
      • AbortEvent -> ResourceAbortEvent
      • ErrorEvent -> ResourceErrorEvent
    • 添加 UnsafeTypedArray 用于在 js! 中以零成本传递切片
    • 添加 Once 用于将 FnOnce 闭包传递给 js!

许可证

在以下许可证下获得许可:

任你选择。

来自 Mozilla 开发者网络 的文档片段受 CC-BY-SA, 版本 2.5 或更高版本的许可。

贡献

请参阅 CONTRIBUTING.md

依赖项

~1.6–2.5MB
~57K SLoC