快速开始
快速开始
环境配置
$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
$ cargo install cargo-generate
$ npm install npm@latest -g
Backend
$ cargo generate --git https://github.com/rustwasm/wasm-pack-template
项目结构如下所示:
├── Cargo.toml
├── LICENSE_APACHE
├── LICENSE_MIT
├── README.md
└── src
├── lib.rs
└── utils.rs
Cargo.toml 文件指定了 Rust 的包管理器和构建工具 Cargo 的依赖关系和元数据。这个文件预先配置了 wasm-bindgen 依赖关系,一些我们稍后会深入研究的可选依赖关系,以及为生成.wasm 库而正确初始化的 crate 类型。src/lib.rs 文件是我们要编译成 WebAssembly 的 Rust crate 的根。它使用 wasm-bindgen 与 JavaScript 接口。它导入了 window.alert 函数,并导出了 greet Rust 函数,该函数会提醒一个问候信息。
extern crate cfg_if;
extern crate wasm_bindgen;
mod utils;
use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;
cfg_if! {
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
if #[cfg(feature = "wee_alloc")] {
extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
}
}
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet() {
alert("Hello, wasm-game-of-life!");
}
src/utils.rs 模块提供了一些常用的实用工具,使编译为 WebAssembly 的 Rust 工作变得更容易。我们将在后面的教程中更详细地介绍其中的一些实用工具,比如当我们研究调试 wasm 代码时,但我们现在可以忽略这个文件。我们使用 wasm-pack
来协调以下构建步骤。
- 确保我们有 Rust 1.30 或更新的版本,并通过
rustup
安装wasm32-unknown-unknown
目标。 - 通过 “cargo “将我们的 Rust 源编译成 WebAssembly
.wasm
二进制。 - 使用 “wasm-bindgen “来生成 JavaScript API,以便使用我们的 Rust 生成的 WebAssembly。
然后运行如下命令:
wasm-pack build
当构建完成后,我们可以在 pkg
目录下找到它的工件,它应该有这些内容。
pkg/
├── package.json
├── README.md
├── hello_world_bg.wasm
├── hello_world.d.ts
└── hello_world.js
.wasm 文件是由 Rust 编译器从我们的 Rust 源代码中生成的 WebAssembly 二进制文件,它包含了所有 Rust 函数和数据的编译到 wasm 版本。它包含了我们所有 Rust 函数和数据的编译到 wasm 版本。例如,它有一个导出的 “greet “函数。.js 文件是由 wasm-bindgen 生成的,它包含了 JavaScript 胶水,用于将 DOM 和 JavaScript 函数导入到 Rust 中,并将 WebAssembly 函数暴露给 JavaScript 一个不错的 API。例如,有一个 JavaScript greet 函数,它包装了从 WebAssembly 模块导出的 greet 函数。现在,这个胶水并没有做什么,但当我们开始在 wasm 和 JavaScript 之间来回传递更多有趣的值时,它将帮助牧羊人将这些值越过边界。
import * as wasm from "./hello_world_bg";
// ...
export function greet() {
return wasm.greet();
}
.d.ts 文件中包含了 JavaScript 胶水的 TypeScript 类型声明,如果你使用 TypeScript,你可以让你对 WebAssembly 函数的调用进行类型检查,你的 IDE 可以提供自动完成和建议。如果你使用 TypeScript,你可以对 WebAssembly 函数的调用进行类型检查,并且你的 IDE 可以提供自动完成和建议!如果你没有使用 TypeScript,你可以安全地忽略这个文件。如果你没有使用 TypeScript,你可以放心地忽略这个文件。
export function greet(): void;
package.json 文件包含了关于生成的 JavaScript 和 WebAssembly 包的元数据。这被 npm 和 JavaScript 捆绑程序用来确定不同包之间的依赖关系、包名、版本和其他一系列东西。它帮助我们与 JavaScript 工具集成,并允许我们将我们的包发布到 npm。
{
"name": "hello_world",
"collaborators": ["Your Name <your.email@example.com>"],
"description": null,
"version": "0.1.0",
"license": null,
"repository": null,
"files": ["hello_world_bg.wasm", "hello_world.d.ts"],
"main": "hello_world.js",
"types": "hello_world.d.ts"
}
Frontend
$ npm init wasm-app www
hello_world/www/
├── bootstrap.js
├── index.html
├── index.js
├── LICENSE-APACHE
├── LICENSE-MIT
├── package.json
├── README.md
└── webpack.config.js
这个 package.json 预先配置了 webpack 和 webpack-dev-server 的依赖,以及对 hello-wasm-pack 的依赖,它是已经发布到 npm 的 wasm-pack-template 初始包的一个版本。这个文件配置了 webpack 和它的本地开发服务器。它是预先配置好的,你不需要调整这个文件就可以让 webpack 和它的本地开发服务器工作。我们不想使用 npm 的 hello-wasm-pack 包,而是想使用我们本地的 hello_world 包。这将允许我们逐步开发我们的生活游戏程序。
{
// ...
"dependencies": {
"hello_world": "file:../pkg" // Add this line!
// ...
}
}
import * as wasm from "hello_world";
wasm.greet();