浏览器/Node环境,使用wasm文件的几种方式
发布于 作者:苏南大叔 来源:程序如此灵动~

本文不涉及wasm
文件的编译,这里假设通过某种编程语言的编译手段,已经得到了一个release.wasm
文件。那么,如何使用这个wasm
文件里面的导出函数呢?这就是本文要讨论的问题。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10
,node@20.18.0
。
前文回顾
如果手里没有合适的标的物release.wasm
文件,可以参考上一篇文章,拿到一个导出函数为add(a,b)
和add2(a,b)
的wasm
文件。
如果拿到的是个完全未知的.wasm
文件,可以参考下面的文章,进行导出函数的分析。
本文的思路上很简单,就是加载.wasm
,然后解析.wasm
,然后执行导出函数。
- 对于不同的使用环境,技术细节是有所不同的。主要的区别就在于如何加载
.wasm
。 - 而关于模块加载
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
起一个容器,是最简单的。不用mime
映射:
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
经验文章,请点击下面的链接:


