前言:WebAssembly(简称wasm)已经出来有几年了,在一些需要高性能的web应用场景中,wasm技术可以让代码执行效率大大提升。react做为目前大厂主流的前端框架之一,搭配上最近几年一直越来越火的Rust语言,可以很好的结合起来,形成wasm的解决方案。国外有高人给出了一篇详细的英文入门教程(见本文最后的参考文章链接),下面是主要使用步骤。

一、准备工作及环境

本文示例环境为:mac环境(12.3.1 Monterey) + nodejs(v 18.5.0) + react (v 18.2) + rustc(v 1.62.0) + cargo(1.57.0) + wasm-bindgen(v 0.2.82) + wasm-pack(v 0.10.3)

请大家先在本机安装好node环境(这是必须的,包括npm包管理工具),另外为了提高一些依赖包的下载速度,建议设置npm的资源为国内淘宝镜像,另外因为要使用rust做为后端语言,所以rust/cargo环境也得有

二、用React脚手架创建项目模板

2.1 先建一个基础目录,比如 wasm_project,进入该目录下

mkdir wasm_project
cd wasm_project

  

2.2 创建react项目模板

npx create-react-app react-wasm-tutorial --template typescript

等待一段时间的下载后,就会创建一个react-wasm-turorial的项目模板,用vscode打开它,可以看看目录结构

就是最常见的react项目结构,其中App.tsx是入口组件,代码如下:

import React from 'react';
import logo from './logo.svg';
import './App.css'; function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
} export default App;

终端窗口下,用npm start把项目跑起来,大致是下面这个样子:

三、创建rust wasm项目

仍然保持在wasm_project/react-wasm-tutorial目录下,终端输入命令:

cargo new wasm-lib --lib

将创建1个rust的lib项目,目录结构如下:

lib.rs中的示例代码没啥用,干掉它,重新写个add加法函数:

// lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
} #[test]
fn add_test() {
assert_eq!(1 + 1, add(1, 1));
}

终端下进入wasm-lib目录后,可以用cargo test测试下代码,正常的话,会看到类似下面的图,表示单元测试通过

到目前为止,所有代码跟wasm半毛钱关系没有,别急!马上就来了:

参考下图,修改Cargo.toml文件,核心就是添加wasm-bindgen依赖,并告诉rust编译器,要生成一个符合C语言规范的动态链接库(C Dynamic Lib)

然后微调lib.rs,参考下图,主要是将add函数标记为允许在wasm环境中调用

依然保持在wasm-lib目录下,安装wasm-pack

cargo install wasm-pack

将rust代码编译成wasm专用的二进制文件,需要这个工具。

停一下,思考1个问题:目前react项目与rust项目,虽然都放在1个根目录下了,但是它俩好象没啥关系? react项目运行时,咋知道要使用rust编译出来的东西呢?

修改package.json,参考下图,加一行:

"build:wasm": "cd wasm-lib && wasm-pack build --target web --out-dir pkg",

这样,我们就能用来编译rust代码来生成wasm

 npm run build:wasm

注:上面的命令,必须在wasm_project/react-wasm-tutorial目录下执行哈。

编译完后,可以看到多出了pkg目录,如下图:

查看wasm_lib.d.ts源码,可以发现add函数已经被export导出了。继续思考一下:pkg目录下生成的东西,react项目在运行时,怎么就知道要加载它呢?大家知道,前端一些依赖的模块,都是放在node_modules下的,所以得将pkg的目录安装到node_modules下

npm install ./wasm-lib/pkg

安装完成后,node_modules目录下就有wasm_lib里的东西了(如下图,基本上就是直接复制过来而已)

可以看到,生成的.wasm文件其实非常小,只有168B。这里再提1个细节,经过刚才这一番折腾后,打开package.json

会发现依赖项里,多出一项"wasm-lib": "file:wasm-lib/pkg"

四、在react中调用wasm

参考下图,修改App.tsx


重新npm run start

可以看到rust里的add,已经在react中调用成功

五、性能对比

原文中这个add太过于简单,体现不出wasm的性能优势,我们来加一个经典的"斐波那契数列"示例

然后参考前面的步骤,重新编译&安装

npm run build:wasm
npm install ./wasm-lib/pkg

然后回到App组件中,调用这个新方法

重新跑一下,观察console控制台的输出:

chrome上的对比效果

firefox上的对比效果:

貌似firefox上wasm的性能提升效果更明显。

六、可能会遇到的坑

6.1、rust中的function,必须定义成pub类型,否则编译时就报错了

6.2、react项目,可以用npm intall xxx 或yarn add xxx来安装包,但是二者别混用(即:一会儿用npm install,一会儿yarn add ),这样node_modules目录,很容易混乱冲突,造成项目启用不了,如果真遇到这种情况

npm install -g rimraf
rimraf node_modules
rimraf package-lock.json
npm cache clear --force
npm config set registry https://registry.npm.taobao.org
npm install

可以在项目根目录下,终端窗口尝试上述命令,重新安装。

附文中示例代码:https://github.com/yjmyzz/react-rust-wasm-demo

参考文章:

https://tkat0.github.io/posts/how-to-create-a-react-app-with-rust-and-wasm

react+rust+webAssembly(wasm)示例的更多相关文章

  1. WebAssembly(wasm)是什么?——学习

    WebAssembly 是一种可以使用非 JavaScript 编程语言编写代码并且能在浏览器上运行的技术方案. 参考文章标题:几张图让你看懂WebAssembly 参考地址:https://www. ...

  2. React的一个简单示例

    首发:个人博客,更新&纠错&回复 React的核心是定义组件类,组件有三个要素:状态.行为.界面. 1.渲染状态到界面:状态由组件对象的state属性持有,从状态到界面的渲染工作由组件 ...

  3. WebAssembly 助力云原生:APISIX 如何借助 Wasm 插件实现扩展功能?

    本文将介绍 Wasm,以及 Apache APISIX 如何实现 Wasm 功能. 作者朱欣欣,API7.ai 技术工程师 原文链接 什么是 Wasm Wasm 是 WebAssembly 的缩写.W ...

  4. [WASM] Compile C Code into WebAssembly

    We use the C language instead of pure WAST to create a square root function using WASM Fiddle (https ...

  5. 【译】Rust宏:教程与示例(一)

    原文标题:Macros in Rust: A tutorial with examples 原文链接:https://blog.logrocket.com/macros-in-rust-a-tutor ...

  6. 荷畔微风 - 在函数计算FunctionCompute中使用WebAssembly

    WebAssembly 是一种新的W3C规范,无需插件可以在所有现代浏览器中实现近乎原生代码的性能.同时由于 WebAssembly 运行在轻量级的沙箱虚拟机上,在安全.可移植性上比原生进程更加具备优 ...

  7. 在kubernetes上运行WASM负载

    在kubernetes上运行WASM负载 WASM一般用在前端业务中,但目前有扩展到后端服务的趋势.本文使用Krustlet 将WASM服务部署到kubernetes. 简介 Krustlet 是一个 ...

  8. SuperEdge: 使用WebAssembly扩展边缘计算场景

    作者 SuperEdge 开发者团队 概要 SuperEdge 是 一个开源的分布式边缘计算容器管理系统,用于管理多个云边区域中的计算资源和容器应用. 在当前架构中,这些资源和应用能够作为一个 Kub ...

  9. 使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍

      使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍 使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍 来自译者 markzhai:大家也知道最近 ...

  10. 前端MVC Vue2学习总结(一)——MVC与vue2概要、模板、数据绑定与综合示例

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.Vue是框架而jQuery则是库. 1.2.AMD与CM ...

随机推荐

  1. Python 3.14 t-string 要来了,它与 f-string 有何不同?

    Python 最近出了个大新闻:PEP-750 t-string 语法被正式采纳了! 这意味着 Python 将在今年 10 月发布的 3.14 版本中引入一种新的字符串前缀 t,称为模板字符串(Te ...

  2. 一些 DP 思维题

    最单纯的思维题就是想出来思路就会做,几乎没有实现难度的题.这种题 CF 与 Atcoder 比较多,这里集中记录一下. 对于 DP 而言,思维题只需要想出转移方程即可. CF1174E Ehab an ...

  3. 5个让你眼前一亮的JavaScript装饰器技巧

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  4. JVM 使用jstat分析系统的垃圾回收情况

    jstat -gcutil 输出结果分析_助你了解jvm命令,查找JVM堆栈信息,分析性能问题.下面介绍一下jstat命令: jstat:虚拟机统计信息监视工具(JVM Statistics Moni ...

  5. 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences

    题意描述 每个栅栏是一条无向边,找出字典序最小的欧拉路.数据保证至少有一个解. 最多 \(500\) 个点, \(1024\) 条边. 分析 看着如此微小的数据范围,随便瞎搞都行使用矩阵来存储边,同时 ...

  6. 通过chrome插件自动生成博客评论,高效发外链

    最近crazy cattle 3d这个词爆火,很多人都在做,竞争异常激烈,甚至可以说是惨不忍睹. 从最近的数据看,胜出的主要是crazycattle3d.com, crazycattle3d.io, ...

  7. 2025私域运营工具攻略:9款AI+SCRM神器助你留存爆发

    私域流量的战火在2025年依旧熊熊燃烧.相比于烧钱获取公域流量,精细化运营私域用户成为越来越多企业的共识.但真正做得好的运营者都明白,留存和转化不是靠刷屏,而是靠体系和工具支撑. 这篇文章,我们将围绕 ...

  8. 你应该懂的AI 大模型(五)之 LangChain 之 LCEL

    本文 对<LangChain>一文中的 Chain 与 LCEL 部分的示例进行详细的展示. 先回顾下 在LangChain框架中,Chain(链) 和 LCEL(LangChain Ex ...

  9. Windows11 关闭搜索栏中的Web网页搜索

    ️ Win11 搜索栏总弹出网页搜索通过注册表彻底关闭 在 Windows 11 系统中,当你通过任务栏中的搜索栏查找内容时,除了显示本地文件.应用和设置外,系统还会自动集成 Bing 搜索结果,展示 ...

  10. 指标+AI:迈向智能化,让指标应用更高效

    近日,以"Data+AI,构建新质生产力"为主题的袋鼠云春季发布会圆满落幕,大会带来了一系列"+AI"的数字化产品与最新行业沉淀,旨在将数据与AI紧密结合,打破 ...