使用Rust和WebAssembly整花活儿(一)——快速开始

一. 前言

WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C / C ++等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。

之前写过一篇文章,是关于如何使用golang来开发WebAssembly的——WebAssembly:未来前端开发的必备技能

Rust和Go都可以用来开发WebAssembly,但它们有各自的优势和劣势。

Rust的优点:

  • 更快的性能和更小的二进制文件
  • 更好的内存安全性

Go的优点:

  • 更容易上手和学习
  • 更好的生态系统和社区支持

综合来说,如果你更注重性能和内存安全性,那么Rust可能是更好的选择。而如果你更注重开发效率和易用性,那么Go可能更适合你。当然,实际情况还需要根据具体的项目需求和团队情况来选择。

因为一些工作需求,最近整了些rust的花活儿,这里系统地记录一下。当你遇到更注重性能和内存安全性的场景,希望这能有帮助。

二. 环境

  • Rust 1.70.0
  • wasm-bindgen 0.2.87

三. 创建项目并添加依赖

此处默认已经安装Rust,需要安装的小伙伴儿可以参考官网

使用Cargo创建一个名为hello-wasm的项目:

cargo new --lib hello-wasm

进入项目,打开文件Cargo.toml,添加依赖:

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.87"

四. 更新lib.rs

默认创建项目中,存在一个名为lib.rs的文件,将内容全部替换成:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
  a + b
}

五. 编译

至此,我们创建了一个最简单的功能——一个返回两个整数相加结果的函数。

然后我们可以进行编译了,编译之前需要安装一个工具wasm-pack

cargo install wasm-pack

然后进行编译:

wasm-pack build --target web

编译完成之后,将会多出来一个pkg文件夹,内容如下:

pkg
├── hello_wasm.d.ts
├── hello_wasm.js
├── hello_wasm_bg.wasm
├── hello_wasm_bg.wasm.d.ts
└── package.json

虽然文件很多,但是首先我们看到了我们所需要的wasm文件,并且,根据go的wasm引入方式,这里我们或许会需要用到js文件。

六. 前端引入

为了方便最快校验,直接在hello-wasm项目中创建index.html文件,来进行前端引入。

1. 创建index.html

那么,首先,创建index.html文件:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用Rust和WebAssembly整花活儿</title>
</head>

<body>
    Hello, World!
</body>

</html>

是的,没错!这是一场标准的开局!😼

2. 引入WASM

其实不同于go语言的wasm引入方式,Rust更希望直接引入js文件,而不是让开发者手动引入wasm文件。

这里使用js引入:

<script type="module">
    import init, { add } from './pkg/hello_wasm.js';

    const run = async () => {
        await init();
        const result = add(1, 2);
        console.log(`the result from rust is: ${result}`);
    }

    run();
</script>

3. 完整代码

完整的html代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用Rust和WebAssembly整花活儿</title>
</head>

<body>
    Hello, World!
</body>

<script type="module">
    import init, { add } from './pkg/hello_wasm.js';

    const run = async () => {
        await init();
        const result = add(1, 2);
        console.log(`the result from rust is: ${result}`);
    }

    run();
</script>

</html>

七. 验证

这里可以快速起一个http server,这里我选择使用http-server,也可以使用python3 -m http.server这样的方式,看怎么各自的使用习惯。

那么,启动http server:

http-server

打开浏览器,访问http://localhost:8080,打开调试器,即可看到输出the result from rust is: 3,这就意味着迈出了整花活儿的第一步!

在这里插入图片描述

八. 常见问题

1. 前端报响应类型错误

详细报错如下:

Failed to load module script: The server responded with a non-JavaScript MIME type of "application/wasm". Strict MIME type checking is enforced for module scripts per HTML spec.

当引入WebAssembly生成的js文件时,可能会遇到这个报错。报错乍一看是http server的响应问题,或者搜索时候,也会有帖子说这是一个response问题。

实际上,当按照这个文章一步步操作时是不会有这个问题的,是因为本文的编译参数是直接解决了这个问题的。当我自己摸索的时候,解决这个问题真的是看到人都麻了……

关键在于编译命令的参数:--target

当没有设置这个参数时,默认的参数其实是--target bundler,其是编译成给webpack之类的脚手架使用的。因此这里使用—target web,则是使其编译成可直接在web中使用。

相关参数如下:

  • bundler:编译成给webpack之类的脚手架使用
  • web:编译成web可直接使用
  • nodejs:编译成可通过require来加载的node模块
  • deno:编译成可通过import加载的deno模块
  • no-modules:跟web类似,但是更旧,且不能使用es模块

2. 直接引入wasm文件

若此时尝试直接引入wasm文件,而不是使用本文所述的方式,那么你会发现,也是可行的!

<script type="module">
    WebAssembly.instantiateStreaming(fetch("./pkg/hello_wasm_bg.wasm"), {}).then(
        (obj) => console.log('the result from rust is: ', obj.instance.exports.add(1, 2))
    );
</script>

是的,没错,当前是可行的,但是当引入了一些别的比如dom之类的,就坏起来了……

3. 更新的wasm引入方式

上一问题中,且不说是否可以直接引入wasm文件,这里仅说一下,instantiateStreaming这个方法。这是一个更新的方法,无需转成arrayBuffer,这也是摸索Rust整活儿时候发现的。如果在别的语言引入wasm,请使用这个更新的方法吧。

九. 原文链接

使用Rust和WebAssembly整花活儿(一)——快速开始

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Rust WebAssembly游戏电子书是一种使用Rust编程语言和WebAssembly技术来制作的电子书,主要面向游戏开发者和编程爱好者。这种电子书结合了Rust的高效性能和WebAssembly的跨平台特性,提供了一种新颖的方式来开发Web游戏Rust是一种现代的系统编程语言,它以安全性、并发性和速度而闻名。Rust游戏可以利用其强大的类型系统和内存安全性来避免一些常见的编程错误,从而提高游戏的稳定性和可靠性。此外,Rust的高性能和优化能力使得游戏在各种平台上都能够快速运行,为玩家提供良好的游戏体验。 WebAssembly是一种可移植的二进制格式,可以在各种浏览器和操作系统上运行。通过将Rust代码编译成WebAssembly游戏可以在Web环境中无缝运行,并且具有与原生应用程序相媲美的性能。由于WebAssembly的跨平台特性,游戏开发者可以轻松地将游戏部署到不同的平台上,无论是桌面、移动设备还是嵌入式系统。 Rust WebAssembly游戏电子书可以帮助游戏开发者快速入门和学习如何使用RustWebAssembly来制作游戏。它提供了详细的教程和示例代码,涵盖了从基本概念到高级技术的各个方面。通过学习这本电子书,开发者可以了解如何使用Rust游戏开发框架和库,如何在WebAssembly中实现游戏逻辑和渲染,以及如何与Web平台进行交互。 总之,Rust WebAssembly游戏电子书是一个有助于开发者学习和掌握使用RustWebAssembly制作游戏的资源。它将Rust的性能和可靠性与WebAssembly的跨平台特性相结合,为游戏开发者提供了一种新的方式来构建高性能、可移植的游戏。 ### 回答2: Rust是一种高性能的系统级编程语言,具有内存安全和并发性。WebAssembly是一种在Web浏览器中运行高性能代码的技术。在RustWebAssembly的结合中,我们可以创建非常出色的游戏和电子书。 使用RustWebAssembly游戏可以带来很多优势。首先,Rust的性能非常出色,能够提供流畅的游戏体验,即使在较低配置的设备上也能运行良好。其次,Rust的内存安全性能让我们可以避免常见的内存错误,如空指针引用和缓冲区溢出。这为游戏开发者提供了更强大的工具,使他们能够编更可靠和稳定的代码。 对于电子书的开发,RustWebAssembly也是一个不错的选择。通过将电子书编译为WebAssembly,我们可以在Web浏览器中交互式地阅读和使用电子书。这为读者提供了更多的功能和交互性,如搜索、高亮、书签等。此外,Rust的内存安全性质使得电子书可以更可靠地加载和运行,避免了常见的安全漏洞和崩溃问题。 总而言之,通过使用RustWebAssembly,我们可以创造出高性能、可靠和交互式的游戏和电子书体验。无论是开发游戏还是电子书,RustWebAssembly是一个令人兴奋和具有潜力的组合,可以为用户带来更加出色的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值