哪些第三方 Crate 可以直接用?
1. 一条经验法则
如果一个 crate 声称支持嵌入式 /
#![no_std]
,那它大概率也能在 WebAssembly 上运行。
原因很简单:
- wasm 环境没有操作系统,等价于“最小裸机”;
#![no_std]
crate 天生不依赖文件系统、线程、动态库等 OS 资源,可直接放到 Wasm 线性内存里执行。
2. 当前在 wasm 上“行不通”的特性
特性 | 为什么不行 | 常见报错 / 行为 |
---|---|---|
依赖系统或 C 库 | Wasm 没有 POSIX / glibc;跨语言 ABI 尚未稳定 | linker error: undefined symbol … |
文件 I/O | 浏览器/JS 运行时无文件系统(除 WASI、虚拟 FS Hack) | 运行期 panic:unable to open file … |
线程 / std::thread | 主流浏览器 Threading & wasm32 目标尚未完全解锁 | 调用时 panic → Wasm trap |
⚠️ 说明
- C FFI:Clang 虽已默认支持
wasm32
, 但跨语言互调 ABI 仍不稳定,需要额外工具链(如wasm32-wasi
+ WASI-libc)才能成功链接。 - 多线程:目前仅有
wasm32-unknown-unknown+atomics
Nightly 试验;生产环境最好避开。 - 文件 I/O:可使用 Fetch AP I / IndexedDB / LocalStorage 替代,或切至
wasm32-wasi
让 WASI 运行时提供虚拟 FS。
3. 哪些通用 Crate 可以直接用?
分类 | 说明 & 代表库 |
---|---|
算法 & 数据结构 | 纯内存操作,不依赖 OS。 例: petgraph (图算法)、rayon-core (需关闭并行) |
#![no_std] 生态 | 任意裸机友好库,如 heapless , embedded-hal (若不涉及硬件 I/O) |
纯解析器 / 序列化 | nom , serde_json (配合 serde 的 alloc 特性) |
文本/Unicode 处理 | unicode-segmentation , pulldown-cmark , regex (开启 wasm-bindgen feature) |
Rust 实用模式库 | thiserror , anyhow , bitflags , smallvec 等均纯 Rust 实现 |
✅ 关键点:不 spawn 线程、不做文件/网络 I/O、不链接 C 动态库。
4. 选型流程 Checklist
- Cargo.toml:查看
dependencies
中是否有-sys
/ffi
/ OS 绑定关键词。 - docs.rs features:确认是否提供
no_std
/wasm-bindgen
/serde
可选特性。 cargo geiger
:检查是否含不安全 FFI、宏等可能调用系统库。- 实测:将项目目标切换到
wasm32-unknown-unknown
,cargo check --target wasm32-unknown-unknown
,编译错误一览无余。
5. 总结
- WASI:为 Wasm 引入类 POSIX 的系统调用,文件读写、tcp/udp 将更简单。
- Component Model:解决 C / Rust / JS 等多语言在 Wasm 内互操作 ABI 问题。
- wasm-threads:浏览器和
wasmtime
等运行时已逐步支持共享内存与原子指令,线程不再遥远。
6.结语
在 WebAssembly 世界,纯算法、无 I/O 的 Rust crates 基本可以“拿来就用”;
涉及系统功能的库则需等待 WASI 与 Component Model 的生态成熟。
提前做好依赖审计,才能让你的 Rust ➜ Wasm 之旅一路畅通!