news 2026/6/11 19:37:08

Rust + WebAssembly 新手完全入门指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Rust + WebAssembly 新手完全入门指南

Rust + WebAssembly 新手完全入门指南

这篇文章面向前端、Rust 开发者,只要跟着步骤就能跑通你的第一个 WebAssembly 前端组件。

WebAssembly 是什么

WebAssembly(简称 Wasm)是一种可在现代浏览器中运行的低级、紧凑、高效的二进制指令格式。它的出现主要是用来解决 JavaScript 天生的性能瓶颈,尤其是计算密集型场景下,WebAssembly 能达到接近原生的执行性能。

可以说,WebAssembly 的出现,使得在网页上运行高级、复杂的客户端应用(如图像编辑、Web AI 推理、复杂的游戏引擎)成为可能。

通过 caniuse,我们可以看到 WebAssembly 在主流浏览器中已经广泛可用,如下图所示:

环境准备

首先,确保你已经安装好 Nodejs 和 Rust 环境。这里我们会用到 wasm-pack,wasm-pack是 Rust Wasm 开发的核心工具,负责构建、打包、测试 Wasm 项目。

# 安装 wasm-packcargoinstallwasm-pack

接下来,我们使用wasm-pack初始化项目:

# 初始化项目wasm-pack new wasm-examplecdwasm-example

wasm-pack会帮我们生成如下的目录结构:

.├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── src │ ├── lib.rs │ └── utils.rs └── tests └── web.rs

wasm-pack初始化项目时默认使用的是 wasm-pack-template 这个模板,由于缺少维护,所以默认使用的Edition、wasm-bindgen 等的版本都比较低,你可以手动调整下,但是在这个案例中,我们就暂时不动它们了。

在以后的开发中,你可以维护一个自己的模板,然后通过如下命令使用模板:

wasm-pack new<name>--template<template>

实现一个简单 Wasm 组件

我们首先实现一个简单 Wasm 组件,我们将会用到 js-sys 这个库,它包含 JavaScript 语言本身的 API,如数组、字符串、console、Promise 等。

# 添加 js-syscargoaddjs-sys

现在我们直接修改src/lib.rs文件:

# 默认模板里有 src/utils.rs,这里引入了它modutils;usewasm_bindgen::prelude::*;#[wasm_bindgen]pubfnsum_array(arr:&js_sys::Array)->u32{letmutsum=0;foriin0..arr.length(){letval=arr.get(i).as_f64().unwrap_or(0.0)asu32;sum+=val;}sum}

#[wasm_bindgen]属性宏声明了将导出sum_array函数以供 JS 调用,这就是我们这个简单组件提供的能力。接下来,我们进行编译:

wasm-pack build--targetweb

编译完成后,我们可以在pkg目录中看到编译结果:

pkg ├── package.json ├── README.md ├── wasm_example_bg.js ├── wasm_example_bg.wasm ├── wasm_example_bg.wasm.d.ts ├── wasm_example.d.ts └── wasm_example.js
  • wasm_example_bg.wasm是核心的 Wasm 二进制文件,包含我们编写的 Rust 逻辑;
  • wasm_example.js是 JS 胶水代码,负责 Wasm 的加载、类型转换,把 Rust 函数封装成 JS 可直接调用的方法;
  • wasm_example.d.ts是 TypeScript 类型定义,用于支持 TS 项目。

这里的--target web表示我们的目标编译平台是 web,这样方便在 HTML 文件中引入。在根目录创建index.html并编辑:

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Rust + WebAssembly</title></head><body><scripttype="module">importinit,{sum_array}from'./pkg/wasm_example.js';awaitinit();console.log("求和结果为:",sum_array([10,20,30]));</script></body></html>

由于浏览器的安全策略不允许加载本地 Wasm 模块,所以无法使用file://协议打开 HTML 文件,我们需要一个本地 HTTP 服务器来启动项目。

npx serve.

这时候,打开浏览器的控制台就能够看到打印出来的求和结果了。

使用 Rust 操作 DOM

借助 web-sys,我们可以直接用 Rust 操作 DOM。与js-sys不同,web-sys包含浏览器环境提供的 Web API。

cargoaddweb-sys--features"Window,Document,HtmlElement"

这里需要注意的是,web-sys必须指定启用的feature,不然编译不通过。

现在我们通过web-sys来修改网页标题,编辑src/lib.rs,添加:

#[wasm_bindgen]pubfnset_title(title:&str){// 1. 获取 window 对象letwin=matchweb_sys::window(){Some(w)=>w,None=>return,};// 获取 document 对象letdoc=matchwin.document(){Some(d)=>d,None=>return,};// 修改网页标题doc.set_title(title);}

重新编译完成后,我们修改index.html,添加:

<scripttype="module">importinit,{set_title,sum_array}from'./pkg/wasm_example.js';awaitinit();console.log("求和结果为:",sum_array([10,20,30]));set_title("Hello world");</script>

刷新网页后,我们就能够看到网页的标题被修改为Hello world了。

接入 Vite

在实际开发中,我们很少直接写原生 HTML,基本上是基于 Vite、Webpack 等构建工具进行开发,这里以最常用的 Vite 为例,演示如何集成 Rust Wasm。

npmcreate vite@latest wasm-vite-example ----templatevanilla-tscdwasm-vite-example

把之前的wasm-example项目整个拷贝到wasm-vite-example的根目录。在实际开发中,这种时候肯定是要用 monorepo 的,但在这个案例中就不这么弄了,一切从简。

.├── .gitignore ├── index.html ├── node_modules ├── package-lock.json ├── package.json ├── public ├── src ├── tsconfig.json └── wasm-example

安装插件:

npminstall-Dvite-plugin-wasm-pack

创建vite.config.ts并编辑:

import{defineConfig}from'vite';importwasmPackfrom'vite-plugin-wasm-pack';exportdefaultdefineConfig({plugins:[wasmPack('./wasm-example')]});

接下来,在src/main.ts中添加上我们之前写的业务逻辑,如下:

importinit,{set_title,sum_array}from'wasm_example'asyncfunctioninitWasm(){awaitinit();console.log("求和结果为:",sum_array([10,20,30]));set_title("Hello world");}initWasm();

启动开发服务:

npmrun dev

打开浏览器就能看到 Wasm 函数的执行结果了。

结尾

至此,我们就成功实现了第一个 WebAssembly 前端组件,虽然它很简陋,没有涉及到:

  • 测试与调试,如:用wasm-pack test进行单元测试、使用浏览器 DevTools 调试 Wasm 代码;
  • Wasm 高级特性,如共享内存、多线程、SIMD 指令等;
  • 性能优化与踩坑。

不过没有关系,这些内容在后续的文章更新中可能会涉及到。现在,我们需要做的是动手实现一遍这个简单的 Wasm 组件。毕竟对于新手而言,最好的学习方式就是动手实践。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/18 22:47:49

【0基础学机器学习】2.决策树

决策树模型笔记 1. 基础知识 基本模型形式 决策树是一种常见的监督学习模型&#xff0c;既可以做分类&#xff0c;也可以做回归。它通过一系列“如果…那么…”的规则不断划分特征空间&#xff0c;最终在叶子节点给出预测结果。 对于分类任务&#xff0c;模型会根据样本特征逐层…

作者头像 李华
网站建设 2026/5/18 22:48:01

SEO_掌握这些SEO核心技巧让你的排名稳步上升

SEO核心技巧&#xff1a;让你的排名稳步上升在互联网时代&#xff0c;拥有一个高排名的网站是吸引流量和提升业务的关键。如果你希望你的网站在百度搜索结果中获得更好的位置&#xff0c;那么掌握一些SEO核心技巧是必不可少的。本文将详细讲解几个关键的SEO技巧&#xff0c;帮助…

作者头像 李华
网站建设 2026/5/18 22:48:03

RemoteDebug:ESP32/ESP8266 WiFi远程调试库深度解析

1. RemoteDebug 库深度解析&#xff1a;面向 ESP32/ESP8266 的嵌入式 WiFi 远程调试系统RemoteDebug 是一款专为 ESP32 和 ESP8266 平台设计的轻量级、高性能远程调试库。它并非简单的Serial.print()替代品&#xff0c;而是一套完整的、工程化程度极高的调试基础设施&#xff0…

作者头像 李华
网站建设 2026/5/18 22:48:00

Arduino I2C LCD驱动库:PCF8574与HD44780通信详解

1. 项目概述LCD_I2C 是一款专为 Arduino 平台设计的轻量级 C 库&#xff0c;用于驱动基于 PCF8574 IC 扩展芯片的 162 字符型液晶显示屏。该库不依赖于 Arduino LiquidCrystal 库的底层并行接口实现&#xff0c;而是完全重构为面向 IC 总线通信的专用驱动架构&#xff0c;通过 …

作者头像 李华