这是一个最基础的 Rust WebAssembly 项目,展示了如何在 Rust 中编写代码并在浏览器中运行。 1
- 🚀 想立即体验? → 小白用户快速指南
- 📦 要集成到项目? → 将 WebAssembly 用到您的项目中
- 🔍 遇到问题? → 故障排除
- 💻 要修改代码? → 高级用户:修改和重新构建
- 📁 找不到文件? → 项目完整结构
🎯 **如果您是第一次接触 WebAssembly,```
rustwasmdemo/ # 📂 项目根目录
├── 🚀 dhgohttp.exe # ⭐ 启动服务器 (双击或命令行运行)
├── 📄 index.html # ⭐ 主演示页面 (浏览器中打开)
├── 📄 README.md # 📖 项目说明文档 (当前文件)
├── 📂 pkg/ # 🎯 分发包 (已生成,可直接使用)mdemo/ # 📂 项目根目录
├── 🚀 dhgohttp.exe # ⭐ 启动服务器 (双击或命令行运行)
├── 📄 index.html # ⭐ 主演示页面 (浏览器中打开)
├── 📄 README.md # 📖 项目说明文档 (当前文件)
├── 📂 pkg/ # 🎯 分发包 (已生成,可直接使用)分!**
### 🚀 零基础快速体验 (3分钟)
1. **📁 下载项目**
- 确保您已经有这个完整的项目文件夹
- 项目里应该包含 `dhgohttp.exe` 文件
2. **🖥️ 启动服务器**
```bash
# 在项目根目录打开命令行/终端,执行:
./dhgohttp.exe
✅ 看到 "服务器启动" 相关信息即表示成功
-
🌐 打开浏览器
- 访问:
http://localhost:8080/index.html - 🎉 您应该能看到一个可交互的 WebAssembly 演示页面!
- 访问:
-
🧪 测试功能
- 在页面上输入数字,点击"加法"、"乘法"按钮
- 输入名字,点击"生成问候语"
- 所有计算都是由 Rust 编写的 WebAssembly 模块完成的!
如果您想在自己的网站/应用中使用这个 WebAssembly 模块:
从 pkg/ 文件夹复制这 3 个文件到您的项目:
您的项目/
├── wasm/ # 新建一个文件夹存放 WASM 文件
│ ├── rustwasmdemo.js # 必需 - JavaScript 接口
│ ├── rustwasmdemo_bg.wasm # 必需 - WebAssembly 核心
│ └── rustwasmdemo.d.ts # 推荐 - TypeScript 类型
创建一个新的 HTML 文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>我的 WebAssembly 应用</title>
</head>
<body>
<h1>WebAssembly 计算器</h1>
<input type="number" id="num1" value="10">
<input type="number" id="num2" value="20">
<button onclick="calculate()">计算</button>
<div id="result"></div>
<script type="module">
// 导入 WebAssembly 模块
import init, { add, multiply, greet } from './wasm/rustwasmdemo.js';
// 初始化模块
await init();
// 定义计算函数
window.calculate = function() {
const a = parseInt(document.getElementById('num1').value);
const b = parseInt(document.getElementById('num2').value);
const sum = add(a, b); // 调用 Rust 函数
const product = multiply(a, b); // 调用 Rust 函数
document.getElementById('result').innerHTML = `
${a} + ${b} = ${sum}<br>
${a} × ${b} = ${product}<br>
${greet('用户')}
`;
};
</script>
</body>
</html># 在您的项目目录下启动服务器
python -m http.server 8080
# 或使用其他 Web 服务器访问 http://localhost:8080/您的文件名.html
Q: 为什么必须用服务器,不能直接双击 HTML 文件?
A: WebAssembly 出于安全考虑,必须通过 HTTP/HTTPS 协议加载
直接打开文件 (file://) 会被浏览器阻止
Q: 我不会编程,可以直接修改这个项目吗?
A: 可以!您可以:
1. 修改 HTML 中的文字、样式
2. 调整输入框的默认值
3. 改变按钮的文字和颜色
但不要修改 pkg/ 文件夹里的内容
Q: 如何添加新的计算功能?
A: 目前项目已包含:add (加法)、multiply (乘法)、greet (问候)、
factorial (阶乘)、is_prime (质数检查)
您可以在 HTML 中调用这些现有函数
Q: 文件太大,如何优化?
A: 当前 WebAssembly 模块仅 34KB,已经很小了
如果需要更小,可以:
1. 只复制 .js 和 .wasm 文件 (不要 .d.ts)
2. 使用 gzip 压缩 (大多数服务器自动支持)
- ✅ 使用 Rust 2024 版本
- ✅ 配置为 WebAssembly 目标 (cdylib)
- ✅ 包含基础的数学运算函数
- ✅ 支持字符串处理
- ✅ 包含高级计算功能 (阶乘、质数检查)
- ✅ 支持浏览器控制台日志输出
- ✅ 完全可用的分发包 (pkg/ 目录)
- ✅ TypeScript 类型定义支持
项目已编译完成,可直接使用!pkg/ 目录包含了完整的分发包:
pkg/
├── rustwasmdemo.js # 7.6KB - JavaScript 绑定层 (必需)
├── rustwasmdemo_bg.wasm # 24.6KB - WebAssembly 二进制 (必需)
├── rustwasmdemo.d.ts # 1.9KB - TypeScript 类型定义 (推荐)
├── rustwasmdemo_bg.wasm.d.ts # 0.7KB - 底层 WASM 类型 (可选)
└── .gitignore # Git 配置 (分发时不需要)
总分发大小: ~34KB (压缩后更小)
| 文件 | 用途 | 是否必需 |
|---|---|---|
rustwasmdemo.js |
JavaScript 绑定层,处理模块加载和数据转换 | ✅ 必需 |
rustwasmdemo_bg.wasm |
编译后的 Rust 代码,核心计算逻辑 | ✅ 必需 |
rustwasmdemo.d.ts |
TypeScript 类型定义,提供类型安全 | 🔶 推荐 |
rustwasmdemo_bg.wasm.d.ts |
底层 WASM 类型定义 | ⚪ 可选 |
add(a: i32, b: i32) -> i32: 两数相加multiply(a: i32, b: i32) -> i32: 两数相乘
greet(name: &str) -> String: 生成个性化问候语
factorial(n: u32) -> u32: 计算阶乘is_prime(n: u32) -> bool: 检查是否为质数
- 控制台日志输出
- 函数调用跟踪
rustwasmdemo/
├── Cargo.toml # 项目配置
├── src/
│ └── lib.rs # Rust 源代码
├── index.html # 完整测试页面 (需要 wasm-pack)
├── README.md # 项目说明
└── target/
└── wasm32-unknown-unknown/
└── release/
└── rustwasmdemo.wasm # 编译后的 WebAssembly 模块
# 项目已编译完成,直接启动服务器
# 使用项目自带的服务器 (推荐)
./dhgohttp.exe
# 服务器将在 http://localhost:8080 启动
# 或使用其他服务器
python -m http.server 8000 # Python (端口 8000)
npx serve . # Node.js 🌐 访问地址:
- 入口页:
http://localhost:8080/index.html(可选择模块版或无模块版) - 模块版直达:
http://localhost:8080/index-modules.html - 无模块版直达:
http://localhost:8080/index-nomodules.html
如果你不想使用 ES Module,而是希望在普通 <script> 标签里直接使用全局变量的方式加载 WASM,可以使用我们已经为你准备好的 no-modules 版本:
- 构建(已构建可跳过)
cargo build --release --target wasm32-unknown-unknown
wasm-bindgen --target no-modules --out-dir pkg-miniprogram --out-name rustwasmdemo --no-typescript target/wasm32-unknown-unknown/release/rustwasmdemo.wasm- 打开页面
- 页面文件:
index-nomodules.html - 依赖文件目录:
pkg-miniprogram/(包含rustwasmdemo.js与rustwasmdemo_bg.wasm)
- 启动本地服务器并访问
./dhgohttp.exe
# 然后在浏览器访问:
# http://localhost:8080/index-nomodules.html在该页面中,wasm-bindgen 以全局变量 wasm_bindgen 暴露 API,初始化代码如下:
<script src="./pkg-miniprogram/rustwasmdemo.js"></script>
<script>
(async function(){
await wasm_bindgen('./pkg-miniprogram/rustwasmdemo_bg.wasm');
// 之后可通过 wasm_bindgen.add / greet / factorial / is_prime 调用
})();
</script>将 pkg/ 目录中的必需文件复制到您的项目:
your-project/
├── libs/
│ ├── rustwasmdemo.js
│ ├── rustwasmdemo_bg.wasm
│ └── rustwasmdemo.d.ts
└── index.html
// ES6 模块方式
import init, {
add,
multiply,
greet,
factorial,
is_prime
} from './libs/rustwasmdemo.js';
async function useWasm() {
// 初始化 WebAssembly 模块
await init();
// 使用函数
console.log(add(10, 20)); // 30
console.log(multiply(5, 6)); // 30
console.log(greet("World")); // "你好, World! 欢迎使用 Rust WebAssembly!"
console.log(factorial(5)); // 120
console.log(is_prime(17)); // true
}
useWasm();import init, {
add,
multiply,
greet,
factorial,
is_prime
} from './libs/rustwasmdemo.js';
async function useWasm(): Promise<void> {
await init();
// TypeScript 会提供完整的类型检查
const sum: number = add(10, 20);
const greeting: string = greet("TypeScript");
const isPrimeResult: boolean = is_prime(17);
}<!DOCTYPE html>
<html>
<head>
<title>WebAssembly Demo</title>
</head>
<body>
<script type="module">
import init, { add, greet } from './libs/rustwasmdemo.js';
init().then(() => {
document.body.innerHTML = `
<h1>${greet('HTML')}</h1>
<p>10 + 20 = ${add(10, 20)}</p>
`;
});
</script>
</body>
</html>
⚠️ 小白用户提示: 如果您只是想使用现有功能,可以跳过这一部分! 当前的pkg/目录已经包含了可用的 WebAssembly 模块。
如果您是开发者,想要修改 Rust 源代码并重新构建:
您需要安装以下工具:
-
Rust 编程语言
# 访问 https://rustup.rs/ 下载安装程序 # 或在终端运行: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
WebAssembly 目标
rustup target add wasm32-unknown-unknown
-
构建工具 (选择一个)
# 推荐方式 cargo install wasm-pack # 或手动方式 cargo install wasm-bindgen-cli
# 在项目根目录执行
wasm-pack build --target web
# 完成后会自动更新 pkg/ 目录# 第一步:编译 Rust 代码为 WebAssembly
cargo build --target wasm32-unknown-unknown --release
# 第二步:生成 JavaScript 绑定
wasm-bindgen --out-dir pkg --web target/wasm32-unknown-unknown/release/rustwasmdemo.wasm主要的 Rust 代码在 src/lib.rs 中:
// 示例:添加一个新的减法函数
#[wasm_bindgen]
pub fn subtract(a: i32, b: i32) -> i32 {
console_log!("计算 {} - {} = {}", a, b, a - b);
a - b
}修改后重新构建:
wasm-pack build --target web# 启动服务器
./dhgohttp.exe
# 在浏览器中访问
http://localhost:8080/index.html构建成功后,pkg/ 目录会包含:
rustwasmdemo.js- 更新的 JavaScript 绑定rustwasmdemo_bg.wasm- 更新的 WebAssembly 二进制rustwasmdemo.d.ts- 更新的 TypeScript 类型定义
rustwasmdemo/ # 📂 项目根目录
├── � dhgohttp.exe # ⭐ 启动服务器 (双击或命令行运行)
├── 📄 index.html # ⭐ 主演示页面 (浏览器中打开)
├── 📄 README.md # 📖 项目说明文档 (当前文件)
├── 📂 pkg/ # 🎯 分发包 (已生成,可直接使用)
│ ├── rustwasmdemo.js # ⭐ JavaScript 绑定层 (必需)
│ ├── rustwasmdemo_bg.wasm # ⭐ WebAssembly 二进制 (必需)
│ ├── rustwasmdemo.d.ts # 📝 TypeScript 类型定义 (推荐)
│ └── rustwasmdemo_bg.wasm.d.ts # 📝 底层类型定义 (可选)
├── 📂 src/ # 💻 Rust 源代码 (开发者用)
│ └── lib.rs # 🦀 主要 Rust 代码
├── 📄 Cargo.toml # ⚙️ Rust 项目配置 (开发者用)
├── 📄 Cargo.lock # 🔒 依赖锁定文件 (自动生成)
└── 📂 target/ # 🔨 构建输出 (自动生成)
└── wasm32-unknown-unknown/
└── release/
└── rustwasmdemo.wasm # 📦 原始 WASM 文件
| 文件/文件夹 | 用途 | 小白用户需要关注吗? |
|---|---|---|
dhgohttp.exe |
启动本地服务器 | ⭐ 是 - 启动服务器必需 |
index.html |
完整演示页面 | ⭐ 是 - 查看效果 |
pkg/rustwasmdemo.js |
JavaScript 接口 | ⭐ 是 - 集成到项目必需 |
pkg/rustwasmdemo_bg.wasm |
WebAssembly 核心 | ⭐ 是 - 集成到项目必需 |
pkg/rustwasmdemo.d.ts |
TypeScript 类型 | 🔶 推荐 - TS 项目需要 |
src/lib.rs |
Rust 源代码 | ❌ 否 - 除非要修改功能 |
Cargo.toml |
项目配置 | ❌ 否 - 除非要修改配置 |
target/ |
构建缓存 | ❌ 否 - 自动生成 |
立即体验:
dhgohttp.exe(启动服务器)index.html(在浏览器查看效果)
集成到项目:
pkg/rustwasmdemo.js(必需)pkg/rustwasmdemo_bg.wasm(必需)pkg/rustwasmdemo.d.ts(TypeScript 用户推荐)
- 模块大小: 仅 34KB (未压缩)
- 加载速度: 毫秒级初始化
- 执行效率: 接近原生性能
- 内存占用: 极低内存开销
- 类型安全: 完整 TypeScript 支持
add(a: number, b: number): number
multiply(a: number, b: number): numbergreet(name: string): stringfactorial(n: number): number // 建议 n <= 10
is_prime(n: number): boolean // 检查质数init(): Promise<void> // 异步初始化模块
main(): void // 模块主函数 (自动调用)- ✅ Chrome 57+
- ✅ Firefox 52+
- ✅ Safari 11+
- ✅ Edge 79+
- ✅ 所有支持 WebAssembly 的现代浏览器
- 🎯 高性能数值计算
- 🎯 算法密集型应用
- 🎯 图像/音频处理
- 🎯 加密解密操作
- 🎯 游戏引擎核心逻辑
- 🎯 科学计算库
- ❌ DOM 操作 (应使用 JavaScript)
- ❌ 简单的 UI 逻辑
- ❌ 网络请求处理
- ❌ 异步事件处理
Q: 双击 dhgohttp.exe 没有反应
A: 解决方法:
1. 右键点击空白处 → "在终端中打开" 或 "打开 PowerShell"
2. 输入: ./dhgohttp.exe
3. 或者按住 Shift + 右键 → "在此处打开命令窗口"
Q: 访问 localhost:8080 显示"无法访问此网站"
A: 检查步骤:
1. 确认命令行窗口还在运行 (不要关闭)
2. 确认地址是 http://localhost:8080/index.html (注意 http://)
3. 尝试 http://127.0.0.1:8080/index.html
4. 检查防火墙是否阻止了 8080 端口
Q: 页面显示 "等待 WebAssembly 模块加载..." 不动
A: 可能原因:
1. pkg 文件夹缺失 → 确保 pkg/ 文件夹在项目根目录
2. 文件路径错误 → 检查 HTML 中的 import 路径
3. 浏览器控制台有错误 → 按 F12 查看控制台错误信息
Q: 点击按钮没有反应
A: 解决步骤:
1. 按 F12 打开开发者工具
2. 查看 Console 标签页有无错误
3. 确认看到 "WebAssembly 模块已加载完成!" 消息
4. 刷新页面重试
Q: 在自己的项目中使用时,显示 "Failed to fetch"
A: 检查清单:
1. 确保通过服务器访问 (不是 file:// 协议)
2. 检查 .wasm 文件是否存在且路径正确
3. 确保服务器支持 .wasm 文件类型
4. 检查浏览器网络标签页查看具体错误
Q: 模块加载失败
A: 确保使用 HTTP 服务器访问,不能直接打开 file:// 协议
WebAssembly 需要通过 HTTP/HTTPS 协议加载
Q: 函数调用报错
A: 确保先调用 await init() 初始化模块
所有 WASM 函数都需要在初始化后才能使用
Q: TypeScript 类型错误
A: 确保导入了 .d.ts 文件
在 tsconfig.json 中包含 pkg 目录
Q: CORS 错误
A: 使用适当的 HTTP 服务器
./dhgohttp.exe (推荐)
python -m http.server 8080
npx serve .
-
查看浏览器控制台
- 按 F12 → Console 标签
- 查看是否有红色错误信息
-
检查网络请求
- 按 F12 → Network 标签
- 刷新页面,查看 .wasm 文件是否成功加载
-
验证文件完整性
# 检查 pkg 目录内容 dir pkg # Windows ls pkg # Mac/Linux # 应该看到: # rustwasmdemo.js # rustwasmdemo_bg.wasm # rustwasmdemo.d.ts
如果遇到其他问题:
- 检查浏览器控制台的完整错误信息
- 确认所有文件都在正确位置
- 尝试使用不同的浏览器测试
- 参考本文档的"小白用户快速指南"部分
[lib]
crate-type = ["cdylib"] # 生成动态链接库用于 WebAssembly
[dependencies]
wasm-bindgen = "0.2" # WebAssembly 绑定
web-sys = { version = "0.3", features = ["console"] } # Web API 访问- 使用
#[wasm_bindgen]宏导出函数到 JavaScript - 支持基础数据类型 (i32, u32, bool, String) 的双向传递
- 提供浏览器控制台日志功能
- 自动初始化模块
想要扩展项目功能?这些想法供参考:
-
更多数据类型支持
- 数组处理 (
Vec<i32>,&[u8]) - 复杂结构体传递
- JSON 数据交互
- 数组处理 (
-
高级算法实现
- 排序算法 (快排、归并)
- 搜索算法 (二分、深度优先)
- 图算法 (最短路径、拓扑排序)
-
性能优化
- SIMD 指令集支持
- 多线程 (Web Workers)
- 内存池管理
项目中也包含了Zig语言编译WebAssembly的示例,以下是常用的编译指令:
⚠️ 重要提示: 本指令适用于 Zig 0.15.1+ 版本。旧版本的编译方法已经过时,请使用以下正确的方法。
# 进入 zigwasm 目录
cd zigwasm
# 编译 WASM 文件
zig build-exe src/main.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall --export=add --export=multiply --export=fibonacci
# 指定输出文件名
zig build-exe src/main.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall --export=add --export=multiply --export=fibonacci --name zigwasm-O Debug- 调试版本,编译快,体积大-O ReleaseSmall- 最小体积,适合Web使用 (推荐)-O ReleaseFast- 最快执行速度-O ReleaseSafe- 安全版本,保留检查
| 参数 | 说明 |
|---|---|
zig build-exe |
构建可执行文件格式 |
-target wasm32-freestanding |
32位WASM目标,无操作系统 |
-fno-entry |
不需要main入口函数 |
--export=函数名 |
导出指定函数供外部调用 |
-O ReleaseSmall |
优化为最小体积 (推荐) |
--name 文件名 |
指定输出文件名 (可选) |
Windows:
cd zigwasm
zig build-exe src/main.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall --export=add --export=multiply --export=fibonacci --name zigwasmLinux/Mac:
cd zigwasm
zig build-exe src/main.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall --export=add --export=multiply --export=fibonacci --name zigwasm# 查看 WASM 文件信息
file zigwasm.wasm
# 查看 WASM 文件大小
ls -lh zigwasm.wasm
# 使用 wasm-objdump 查看导出函数 (需要安装 wabt)
wasm-objdump -x zigwasm.wasmzigwasm/
├── build.zig # 标准构建脚本
├── build_wasm.zig # WASM专用构建脚本
├── build.zig.zon # 项目配置
├── src/
│ ├── main.zig # 主要源代码
│ └── root.zig # 模块根文件
├── tools/
│ └── count-wasm-tables.ps1 # 分析工具
└── zigwasm.wasm # 编译输出 (生成后)
- wasm-pack: WebAssembly 包构建工具
- wasm-bindgen: Rust 和 JavaScript 绑定
- web-sys: Web API 绑定
- js-sys: JavaScript API 绑定
这个项目仅用于学习和演示目的。您可以自由使用、修改和分发。
欢迎提交 Issue 和 Pull Request 来改进这个项目!
🎉 恭喜!您已经成功创建了一个完整可用的 Rust WebAssembly 项目!
现在您可以:
- ✅ 直接使用
pkg/目录中的文件 - ✅ 在任何支持 ES6 模块的项目中集成
- ✅ 享受 TypeScript 的完整类型支持
- ✅ 体验接近原生的执行性能
Happy coding with Rust and WebAssembly! 🦀✨