前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >通过从JavaScript调用Rust来构建和扩充库【Programming(JavaScript)】

通过从JavaScript调用Rust来构建和扩充库【Programming(JavaScript)】

作者头像
Potato
修改于 2019-11-25 07:13:20
修改于 2019-11-25 07:13:20
2.8K00
代码可运行
举报
运行总次数:0
代码可运行

探索如何使用WebAssembly(Wasm)将Rust嵌入JavaScript。

图片来源:Alex Sanchez. CC BY-SA 4.0.
图片来源:Alex Sanchez. CC BY-SA 4.0.

在《为什么要在WebAssembly中使用Rust?》中,我探讨了为什么您可能要编写WebAssembly(Wasm),以及为什么选择Rust作为其语言。现在,我将通过探索将Rust嵌入JavaScript的方式来分享这个过程。

这是将Rust与Go,C#和其他大型语言(具有可编译为Wasm的大型运行时)区分开来的功能。Rust的运行时最少(基本上只是一个分配器),可以轻松地从JavaScript库使用Rust。C和C++相似,但是Rust的独特之处在于它的工具,现在我们来看一下。

基本知识

如果您以前从未使用过Rust,那么您首先需要进行设置。很简单首先下载Rustup,这是一种控制Rust版本和不同工具链进行交叉编译的方式。这将使您可以访问Cargo,这是Rust构建工具和包管理器

现在我们要做出决定。我们可以很容易地编写通过WebAssembly在浏览器中运行的Rust代码,但是如果我们不想让人们的CPU风扇疯狂旋转,我们可能会在某个时候想与文档对象模型(DOM)进行交互或使用一些JavaScript API。 换句话说,我们需要 JavaScript 互操作(也就是 JavaScript 互操作 API)。

问题与解决方案

WebAssembly是一种非常简单的机器语言。如果我们希望能够与JavaScript进行通信,Wasm仅提供四种数据类型来进行处理:32位和64位浮点数和整数。Wasm没有字符串,数组,对象或任何其他丰富数据类型的概念。基本上,我们只能在Rust和JavaScript之间传递指针。不用说,这不是理想的。

好消息是,有两个库可促进基于Rust的Wasm与JavaScript之间的通信:wasm-bindgenstdweb。然而,坏消息是,这两个库互不兼容。Wasm-bindgen比stdout更底层,它试图提供对JavaScript和Rust交互方式的完全控制。实际上,甚至有人在谈论使用wasm-bindgen重写stdweb,这将解决不兼容的问题。

因为wasm-bindgen是更轻量级的选项(该选项由Rust WebAssembly官方工作组正式开发),所以我们将重点讨论这个选项。

wasm-bindgen和wasm-pack

我们将创建一个函数,该函数从JavaScript中获取字符串,将其变为大写并在其前面加上“HELLO”,然后将其返回给JavaScript。 我们称这个函数为excited_greeting !

首先,让我们创建一个Rust库,其中将包含这个函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cargo new my-wasm-library --lib
 $ cd my-wasm-library

现在,我们要用令人兴奋的逻辑替换src / lib.rs的内容。 我认为最好自己尝试写出代码而不是复制/粘贴。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Include the `wasm_bindgen` attribute into the current namespace.
 use wasm_bindgen::prelude::wasm_bindgen;
 
 // This attribute makes calling Rust from JavaScript possible.
 // It generates code that can convert the basic types wasm understands
 // (integers and floats) into more complex types like strings and
 // vice versa. If you're interested in how this works, check this out:
 // https://blog.ryanlevick.com/posts/wasm-bindgen-interop/
 #[wasm_bindgen]
 // This is pretty plain Rust code. If you've written Rust before this
 // should look extremely familiar. If not, why wait?! Check this out:
 // https://doc.rust-lang.org/book/
 pub fn excited_greeting(original: &str) -> String {
   format!("HELLO, {}", original.to_uppercase())
 }

其次,我们必须对Cargo.toml配置文件进行两项更改:

  • 添加wasm_bindgen作为依赖项。
  • 将库二进制文件的类型配置为cdylib或动态系统库。在这种情况下,我们的系统是wasm,设置此选项是我们产生.wasm二进制文件的方式。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[package]
 name = "my-wasm-library"
 version = "0.1.0"
 authors = ["$YOUR_INFO"]
 edition = "2018"
 
 [lib]
 crate-type = ["cdylib", "rlib"]
 
 [dependencies]
 wasm-bindgen = "0.2.33"

现在开始构建! 如果仅使用cargo build ,我们将获得一个.wasm二进制文件,但是为了使从JavaScript调用Rust代码更容易,我们希望有一些JavaScript代码可以将丰富的JavaScript类型(例如字符串和对象)转换为指针,并代表我们将这些指针传递给Wasm模块。 手动执行此操作很繁琐且容易出现错误。

幸运的是,wasm-bindgen不仅仅只是一个库,它还具有为我们创建一种“胶水”JavaScript的能力。 这意味着在我们的代码中,我们可以使用普通的JavaScript类型与Wasm模块进行交互,并且wasm-bindgen生成的代码将完成将这些丰富的类型转换为Wasm真正理解的指针类型的工作。

我们可以使用wasm-pack来构建Wasm二进制文件,调用wasm-bindgen CLI工具,然后将所有JavaScript(以及任何可选的生成的TypeScript类型)打包到一个简洁的程序包中。 现在就开始吧!

首先,我们需要安装wasm-pack :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cargo install wasm - pack

默认情况下,wasm-bindgen 生成 ES6模块。 我们将使用来自一个简单脚本标记的代码,因此我们只希望它生成一个普通的旧JavaScript 对象,使我们能够访问 Wasm 函数。 为此,我们将传递 -- target no-modules 选项。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ wasm - pack build -- target no - modules

现在,我们的项目中有一个pkg目录。 如果我们查看内容,将会看到以下内容:

  • package.json :如果我们要将其打包为NPM模块,则很有用
  • my_wasm_library_bg.wasm :我们实际的Wasm代码
  • my_wasm_library.js :JavaScript“胶水”代码
  • 一些TypeScript定义文件

现在,我们可以创建一个index.html文件,该文件将使用我们的JavaScript和Wasm:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<html>
 <head>
  <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
 </head>
 <body>
  <!-- Include our glue code -->
  <script src='./pkg/my_wasm_library.js'></script>
  <!-- Include our glue code -->
  <script>
     window.addEventListener('load', async () => {
       // Load the wasm file
       await wasm_bindgen('./pkg/my_wasm_library_bg.wasm');
       // Once it's loaded the `wasm_bindgen` object is populated
       // with the functions defined in our Rust code
       const greeting = wasm_bindgen.excited_greeting("Ryan")
       console.log(greeting)
     });
  </script>
 </body>
 </html>

你可能想在浏览器中打开HTML文件,但不幸的是,这是不可能的。出于安全原因,Wasm文件必须与HTML文件来自同一个域。你需要一个HTTP服务器。如果您有一个最喜欢的静态HTTP服务器,可以从您的文件系统提供文件,请随意使用它。我喜欢使用basic-http-server,你可以像这样安装和运行它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cargo install basic-http-server
 $ basic-http-server

现在通过web服务器打开索引.html文件,访问googlehttp://localhost:4000/index.html并检查你的JavaScript控制台。你应该看到一个非常令人兴奋的问候!

如有任何疑问,请告诉我们。下次,我们将研究如何在Rust代码中使用各种浏览器和JavaScript API。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Rust实现MD5加密并打包成WebAssembly调用
我初识 WebAssembly 是当初想要分析某个网站的加密算法,最终定位到了一个 .wasm 文件,没错,这个就是 WebAssembly 的构建产物,能够直接运行在浏览器中。在我当时看来这门技术很先进,不过如今看来绝大多数的 web 应用貌似都没使用上,迄今为止我也只在这个网站中看到使用 WebAssembly 的(也许有很多,只是没实质分析过)。
愧怍
2023/01/05
2.9K0
Rust实现MD5加密并打包成WebAssembly调用
使用 Rust 编写更快的 React 组件
大家好,我是 ConardLi,上周发了一篇 Wasm 的文章,主要分析的是今年 Google 开发者大会上的 Wasm 主题:
ConardLi
2021/12/02
1.2K0
使用 Rust 编写更快的 React 组件
Rust 编译为WebAssembly 在前端项目中使用
最近,不是加大了对Rust相关文章的输出吗,在评论区或者私信区。有一些不同的声音说:“Rust没有前途,然后...."。其实呢,看一个技术是否有需要学习的动力。想必大家的底层理由都是「一切都是向钱看」,毕竟在国内大家都是业务为主,想自己纯手搞一套符合自己的技术框架和范式,这是不切实际的。(当然也不能一杆子打死,还是有很多技术大牛的)现在大家纠结或者对这个技术属于观望态度,无非就是在平时开发工作中没有涉及到的点。
前端柒八九
2023/10/25
1.1K0
Rust 编译为WebAssembly 在前端项目中使用
Rust与WebAssembly:构建跨平台应用的实战指南
WebAssembly (Wasm) 是一种可以在现代Web浏览器中运行的高效、低级字节码格式。它提供了跨平台执行环境,能够以接近本地速度运行,并且可以通过多种编程语言(如C、C++、Rust等)编译到Wasm格式。Rust作为一种内存安全、高性能的系统编程语言,已成为编译到WebAssembly的理想选择。
数字扫地僧
2024/12/15
3140
Rust 赋能前端 -- 写一个 File 转 Img 的功能
大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder
前端柒八九
2024/05/28
3100
Rust 赋能前端 -- 写一个 File 转 Img 的功能
WebAssembly + Rust 上手初探
如果说现在还有什么技术能够掀起前端的大变革,那就是 WebAssembly 了(以下简称WASM)。WASM 技术从立项开始便受到大家的瞩目,随着各大浏览器厂商的努力,目前的主流浏览为已经全部完成对 WebAssembly 的初步实现。另外在社区的推动下,围绕 WASM 的 emscripten 和 wasm-pack 等工具链的支持已经日趋完善,是时候使用 WebAssembly 了!
IMWeb前端团队
2019/12/03
1.1K0
WebAssembly + Rust 上手初探
纵论WebAssembly,JS在性能逆境下召唤强援
webassembly是一种底层的二进制数据格式和一套可以操作这种数据的JS接口的统称。我们可以认为webassembly的范畴里包含两部分
啦啦啦321
2019/12/11
1K0
尝试用 Rust + Yew 写高性能前端页面
看到这篇文章,可能很多人会有个疑问:“已经有 React + TypeScript 这么好的组合,为什么还想着使用 Rust 来写前端页面,不折腾吗?”
winty
2021/05/18
2.6K0
尝试用 Rust + Yew 写高性能前端页面
基于IM场景下的Wasm初探:提升Web应用性能|得物技术
Wasm,全称 WebAssembly,官网描述是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm被设计为一个可移植的目标,用于编译C/C++/Rust等高级语言,支持在Web上部署客户端和服务器应用程序。
得物技术
2024/11/05
2870
基于IM场景下的Wasm初探:提升Web应用性能|得物技术
入门 Rust 开发 WebAssembly
本文来自 AirCloud 的知乎投稿:https://zhuanlan.zhihu.com/p/104299612
MikeLoveRust
2020/02/20
1.6K0
宝贝,带上WebAssembly,换个姿势来优化你的前端应用
大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder
前端柒八九
2024/06/07
4150
宝贝,带上WebAssembly,换个姿势来优化你的前端应用
react+rust+webAssembly(wasm)示例
前言:WebAssembly(简称wasm)已经出来有几年了,在一些需要高性能的web应用场景中,wasm技术可以让代码执行效率大大提升。react做为目前大厂主流的前端框架之一,搭配上最近几年一直越来越火的Rust语言,可以很好的结合起来,形成wasm的解决方案。国外有高人给出了一篇详细的英文入门教程(见本文最后的参考文章链接),下面是主要使用步骤。
菩提树下的杨过
2022/08/23
1.6K0
react+rust+webAssembly(wasm)示例
Rust 和 Wasm 的融合,使用 yew 构建 WebAssembly 标准的 web 前端 - 起步及 crate 选择
在以前的构建 Rust 异步 GraphQL 服务系列中,分别采用 tide + async-graphql + mongodb 和 actix-web + async-graphql + rbatis + postgresql / mysql 开发了 GraphQL 服务后端。感兴趣的朋友可以参阅博文——
niqin.com
2022/09/01
1.9K0
都2021年了,你怎么还在说webassembly?
What is webssembly 首先,按照惯例,科普下啥是 webssembly 一种新的、抽象的虚拟机指令集(W3C)标准; 四大浏览器已经支持该标准 MVP 版本的所有特性; 一种以.wasm未后缀的二进制格式; 可以通过标准的Web API接口在浏览器中加载、解析和执行; Why is webssembly 那么,这玩意是为啥而诞生的呢? 那就得从1995年说起了,那一年,我刚学会走路,Javascript 诞生了,并且从此一发不可收拾,推动了web的迅速发展。如果把WEB看作是一辆车,那
QQ音乐前端团队
2021/05/28
16.6K1
Rust 赋能前端:图片OCR识别,以后可以抛弃tesseract了
大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder
前端柒八九
2025/01/03
3160
Rust 赋能前端:图片OCR识别,以后可以抛弃tesseract了
【Rust每周一库】Yew - Rust语言实现的WebAssembly多线程前端框架
Yew是一个设计先进的Rust前端框架,目的是使用WebAssembly来创建多线程前端web应用。
MikeLoveRust
2020/05/22
1.5K0
一文带你走进 Rust 和 WebAssembly 的世界
在进行正式的分享之前,先来说一说为什么,要学习 Rust 这一门在广义上归属于后端的语言,以及它能带给我们什么,未来有什么前景。
童欧巴
2021/08/20
2.2K0
一文带你走进 Rust 和 WebAssembly 的世界
Rust 赋能前端: 视频抽帧
大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder
前端柒八九
2025/01/03
2110
Rust 赋能前端: 视频抽帧
如何优雅地打包非 JavaScript 静态资源
假设你正在开发一个网络应用程序。在这种情况下,你很可能不仅要处理 JavaScript 模块,还要处理各种其他资源--Web Workers(它也是 JavaScript ,但它拥有一套独立的构建依赖图)、图片、CSS、字体、WebAssembly 模块等等。
coder_koala
2021/11/10
1.4K0
如何优雅地打包非 JavaScript 静态资源
CloudBluePrint-Chapter 1.8 : 云上应用技术架构-WebAssembly (WASM)
从物理机,到虚拟机,再到容器引擎,最后到WebAssembly,计算领域的技术趋势主要包括以下几个方面:
行者深蓝
2023/09/07
6910
推荐阅读
相关推荐
Rust实现MD5加密并打包成WebAssembly调用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验