浏览器/Node环境,使用wasm文件的几种方式
发布于 作者:苏南大叔 来源:程序如此灵动~
本文不涉及wasm文件的编译,这里假设通过某种编程语言的编译手段,已经得到了一个release.wasm文件。那么,如何使用这个wasm文件里面的导出函数呢?这就是本文要讨论的问题。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10,node@20.18.0。
前文回顾
如果手里没有合适的标的物release.wasm文件,可以参考上一篇文章,拿到一个导出函数为add(a,b)和add2(a,b)的wasm文件。
如果拿到的是个完全未知的.wasm文件,可以参考下面的文章,进行导出函数的分析。
本文的思路上很简单,就是加载.wasm,然后解析.wasm,然后执行导出函数。
- 对于不同的使用环境,技术细节是有所不同的。主要的区别就在于如何加载
.wasm。 - 关于
js模块加载import和require的区别,这里并没有涉及到。因为是通过WebAssembly.instantiate()来导入的。
纯node环境
在纯node环境下,是使用fs模块来加载.wasm文件的。范例t.js如下:
const fs = require('fs');
const wasmBuffer = fs.readFileSync('release.wasm');
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
const { add, add2 } = wasmModule.instance.exports;
console.log(add(1, 2)); // 输出 3
console.log(add2(3, 4)); // 输出 8
});
当然,也可以改成import('fs')。范例t.mjs【注意,这里是.mjs文件】如下:
import fs from 'fs';
const wasmBuffer = fs.readFileSync('release.wasm');
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
const { add, add2 } = wasmModule.instance.exports;
console.log(add(1, 2)); // 输出 3
console.log(add2(3, 4)); // 输出 8
});浏览器环境
下面的代码,只能在浏览器环境下执行。因为fetch()函数并不支持file协议。注意配置容器及mime映射。
fetch('./release.wasm')
.then(rep => rep.arrayBuffer()) // 转 ArrayBuffer
.then(bytes => WebAssembly.compile(bytes)) // 编译为 module 对象
.then(module => WebAssembly.instantiate(module)) // 创建 instance 对象
.then(instance => {
const { add, add2 } = instance.exports;
console.log(add(1, 2));
console.log(add2(1, 3));
});
WebAssembly.instantiateStreaming(fetch('./release.wasm')).then(res => {
const { module, instance } = res;
const { add, add2 } = instance.exports;
console.log(add(1, 2));
console.log(add2(1, 3));
});虽然现在的纯node环境下,也有fetch函数。但是,这个fetch()和php的file_get_contents()还是有所区别的。它不支持读取本地,只支持读取网络文件。
但是,可能会碰到下面的报错问题。
mime 映射
报错信息如下:
Uncaught (in promise) TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.可能的解决方案:
如果是测试的话,直接用python起一个容器,是最简单的。不需要做什么设置,最简单:
python -m http.server 8080跨域
已拦截跨源请求:同源策略禁止读取位于 file:///C:/Users/sunan/Desktop/t/release.wasm 的远程资源。(原因:CORS 请求不是 http)。或者:
Access to fetch at 'file:///C:/Users/sunan/Desktop/t/release.wasm' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrome-extension, chrome-untrusted, data, http, https, isolated-app.解决方案:不要双击打开,请放置到容器(例如nginx)内,然后访问网络地址。
相关文档
参考文章:
- https://developer.mozilla.org/en-US/docs/WebAssembly
- https://nodejs.org/api/esm.html
- https://rustwasm.github.io/docs/book/
- https://github.com/rustwasm/wasm-bindgen/
结语
更多苏南大叔的wasm经验文章,请点击下面的链接: