Rust 编译为 WebAssembly 在前端项目中使用(一)

简介: Rust 编译为 WebAssembly 在前端项目中使用(一)

过去属于死神,未来属于你自己。——雪莱

大家好,我是柒八九

前言

最近,不是加大了对Rust相关文章的输出吗,在评论区或者私信区。有一些不同的声音说:“Rust没有前途,然后...."。其实呢,看一个技术是否有需要学习的动力。想必大家的底层理由都是一切都是向钱看,毕竟在国内大家都是业务为主,想自己纯手搞一套符合自己的技术框架和范式,这是不切实际的。(当然也不能一杆子打死,还是有很多技术大牛的)现在大家纠结或者对这个技术属于观望态度,无非就是在平时开发工作中没有涉及到的点。

同时,由于国内技术的滞后性,有一些应用场景其实还是处于蛮荒的状态。(不是崇洋媚外,事实确实如此)。所以,在一些可以用到新的技术点的方向上,国内还是处于蓝海阶段。

所以,本着对该技术的独有关注度,我还是选择义无反顾的投身到学习和实际中。冲破黎明之前的黑暗,你会拥有太阳,而晨曦中第一缕阳光也是为你而耀眼

image.png

而具体,Rust到底能给你带来点啥,我们之前有文章讲过,这里就不在赘述了。

Last but not leaset,由于现在本人暂时专注于前端领域居多,所以我更多关注Rust能为前端带来点啥。而说到Rust和前端,第一点的联想就是:WebAssembly。(如果,不了解何为WebAssembly,可以参考我们之前的文章浏览器第四种语言-WebAssembly,里面的例子是用Emscripten写的)

其实,我们之前写过如何用Cwasm,也写过WebAssembly-C与JS互相操作等文章。但是,由于一些不可言喻的原因搁置了。

我们今天将使用Rust创建一个WebAssembly Hello World程序。我们将深入了解由wasm-bindgen生成的代码,以及它们如何共同协作来帮助我们进行开发。我们还将使用wabt来探索生成的wasm代码。这将使我们更好地理解Rust WebAssembly,并为我们的开发奠定良好的基础。

好了,天不早了,干点正事哇。


我们能所学到的知识点

  1. 前置知识点
  2. 项目搭建
  3. 原理探析
  4. 内容拓展

1. 前置知识点

前置知识点,只是做一个概念的介绍,不会做深度解释。因为,这些概念在下面文章中会有出现,为了让行文更加的顺畅,所以将本该在文内的概念解释放到前面来。如果大家对这些概念熟悉,可以直接忽略


同时,由于阅读我文章的群体有很多,所以有些知识点可能我视之若珍宝,尔视只如草芥,弃之如敝履。以下知识点,请酌情使用

安装Rust

如果是你一个Rust萌新,我们也给你提供Rust环境配置和入门指南

如果,想独立完成安装,可以到Rust 安装页面跟着教程安装。

在安装成功Rust后,它会安装一个名为rustup的工具,这个工具能让我们管理多个不同版本的 Rust。默认情况下,它会安装用于惯常 Rust 开发的 stable 版本 Rust Release

Rustup 会安装

  • Rust 的编译器 rustc
  • Rust 的包管理工具 cargo
  • Rust 的标准库 rust-std
  • 以及一些有用的文档 rust-docs

因为,我本机已经安装好了Rust。我们可以通过rustup --version来查看rustup的版本。以下是我本机的rustup版本信息。下文中所有的代码,都基于该版本。

rustup --version
rustup 1.26.0 (5af9b9484 2023-04-05)

安装WebAssembly二进制工具包(wabt)

image.png

这些工具旨在用于开发工具链或其他系统,这些系统希望操作WebAssembly文件。与WebAssembly规范解释器不同(该解释器旨在尽可能简单、声明性和“规范性”),这些工具是用C/C++编写的,并设计成更容易集成到其他系统中。这些工具不旨在提供优化平台或更高级的编译目标;相反,它们旨在实现与规范的完全适应和遵从。

我们可以利用brew来在Mac环境下安装。

image.png


2. 项目搭建

2.1 安装wasm-bindgen

我们可以通过cargo install --list来查看在$HOME/.cargo/bin位置安装过的Rust二进制文件。

在一些其他的教程中可以不使用wasm-bindgen构建Hello World程序,但是在本文中,我们将使用它,因为它在Rust WebAssembly开发中是必不可少的。

cargo install wasm-bindgen-cli

Rust WebAssembly允许我们将WebAssembly模块有针对性地插入到现有的JavaScript应用程序中,尤其是在性能关键的代码路径中。我们可以将wasm-bindgen视为一种工具,它通过生成用于JavaScriptWebAssembly之间高效交互的粘合代码和绑定来帮助我们实现丝滑的交互体验。


2.2 创建Rust WebAssembly项目

巴拉拉小魔仙,念诵如下咒语,构建一个Rust WebAssembly项目。

cargo install wasm-bindgen-cli

上面的代码是使用Cargo工具创建一个新的Rust项目,项目的名称是hello_world,并且指定它是一个库(--lib)。这将创建一个包含基本项目结构的文件夹,其中包括一个Cargo.toml文件和一个src文件夹。

+-- Cargo.toml
+-- src
    +-- lib.rs
  • Cargo.toml文件用于管理项目的依赖和配置
  • src文件夹包含项目的Rust源代码文件
  • 项目名称hello_world是一个示例名称,我们可以根据自己的需求为项目指定不同的名称。

2.3 修改Cargo.toml配置项

使用宇宙最强IDE -VScode,打开Cargo.toml文件。我们应该会看到以下内容。

[package]
name = "hello_world"
version = "0.1.0"
authors = ["789"]
edition = "2021"
[dependencies]

将其修改成下面的内容

[package]
name = "hello_world"
version = "0.1.0"
authors = ["789"]
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"

上面的大部分字段大家都能看懂,其中lib项的配置,这里稍微解释一下:

crate-type = ["cdylib"]: 这一行指定了生成的库的类型。在这里,crate-type 设置为["cdylib"],这表示我们正在创建一个动态链接库(C-compatible dynamic library)。这用于编译一个供其他编程语言加载的动态库。此输出类型将在Linux上创建*.so文件,在macOS上创建*.dylib文件,在Windows上创建*.dll文件。

这种类型的库可以被其他编程语言调用,因为它们与C语言兼容。这对于与WebAssembly(Wasm)互操作性很重要,因为Wasm通常需要与C语言接口进行交互。因此,cdylib 表示该库是一个可供其他语言使用的动态链接库


2.4 编辑lib.rs

打开src/lib.rs文件。将其更改为以下内容:

extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
// 导入 'window.alert'
#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}
// 导出一个 'helloworld' 函数
#[wasm_bindgen]
pub fn helloworld(name: &str) {
    alert(&format!("Hello World : {}!", name));
}

我们简单解释一下核心代码:

  1. extern crate wasm_bindgen;: 这一行声明了对wasm_bindgen库的依赖。wasm_bindgen是一个Rust库,用于构建Wasm模块并提供与JavaScript的互操作性。在 Rust 当中,库被称为crates,因为我们使用的是一个外部库,所以有 extern
  2. use wasm_bindgen::prelude::*;: 这一行导入了wasm_bindgen库的预导出(prelude)模块中的所有内容,以便在后续代码中使用。

在 Rust 中调用来自 JavaScript 的外部函数

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

#[wasm_bindgen]: 在 #[] 中的内容叫做 "属性",并以某种方式改变下面的语句。#[wasm_bindgen]是一个属性标记,用于指定与WebAssembly互操作相关的特性。

extern "C" { fn alert(s: &str); }: 这里声明了一个外部函数alert,它使用extern "C" 指定了C ABI(应用二进制接口),这意味着它可以与C语言进行交互这个alert函数没有在Rust中实现,而是在JavaScript中实现,用于在浏览器中显示警告框

在 JavaScript 中调用的 Rust 函数

#[wasm_bindgen]
pub fn helloworld(name: &str) {
    alert(&format!("Hello World : {}!", name));
}

#[wasm_bindgen] pub fn helloworld(name: &str): 这是一个Rust函数helloworld,它被标记为wasm_bindgen,这意味着它可以被JavaScript调用。这个函数接受一个字符串参数name,然后调用之前声明alert函数,以显示带有Hello World消息的弹框,并在消息中包括name参数的内容。

2.5 编译代码

在命令行中输入以下命令:

cargo build --target wasm32-unknown-unknown

如果未安装对应的库,控制台会给出提示。

image.png

那我们就照猫画虎的操作一下:

bash

复制代码

rustup target add wasm32-unknown-unknown
  1. cargo build: 这是 Cargo 工具的命令,用于构建 Rust 项目。它会编译项目的源代码并生成可执行文件或库文件,具体取决于项目的类型。
  2. --target wasm32-unknown-unknown: 这部分是构建的目标参数。--target 标志用于指定要构建的目标平台。在这里,wasm32-unknown-unknown 是指定了 WebAssembly 目标平台。这告诉 Cargo 生成适用于 WebAssembly 的二进制文件,而不是生成本地平台的二进制文件。

当运行这个命令后,Cargo 会使用 Rust 编译器(Rustc)以及与 WebAssembly 相关的工具链,将 Rust 代码编译为 WebAssembly 格式的二进制文件。这个生成的 Wasm 文件可以在浏览器中运行,或与其他支持 WebAssembly 的环境一起使用。

运行结果如下:

image.png

cargo build --target wasm32-unknown-unknown 命令的默认输出位置是在项目的 target 目录下,具体位置是:

target/wasm32-unknown-unknown/debug/

在这个目录下,我们会找到生成的 WebAssembly 文件(通常是一个 .wasm 文件),以及其他与编译过程相关的文件。

image.png

相关文章
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
751 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1001 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
548 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
804 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
1010 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
525 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
1596 14
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
1018 0
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架

热门文章

最新文章