我正试图在NextJs项目中使用一个rust-generated wasm模块。
我以以下方式导入废物:
import init, { tokenize } from "@/wasm/lazyjson";
const Test = dynamic({
loader: async () => {
await init();
console.log(tokenize("[]"));
return function Yay() {
return <p>hi</p>;
};
},
});
我还试着用导入它
const { default: init, tokenize } = await import("@/wasm/lazyjson");
这导致
TypeError: Only absolute URLs are supported
从webpack 5(NextJs使用(开始,WebAssembly默认支持(我认为(。这是我的next.config.js
/webpack配置:
module.exports = {
webpack: (config) => {
config.resolve.alias["@/"] = __dirname;
return config;
},
};
我已经尝试添加syncWebAssembly
标志
config.experiments = { syncWebAssembly: true };
这导致了一个不同的错误:
Module not found: Can't resolve 'wbg' in '[project-path]wasmlazyjson'
如果你对这个问题感到困惑或需要更多的上下文,请查看我在这里打开的问题。它还包含复制步骤。
不要依赖第三部分库,而是将wasm文件夹放在public
文件夹中,然后在客户端简单地获取它。
async function getWasm() {
try {
const res = await fetch("test.wasm");
// bytes from memory
const buffer = await res.arrayBuffer();
// this will create an object
// WebAssembly is part of window api. so make sure you are on client side.
const wasm = await WebAssembly.instantiate(buffer);
console.log(wasm);
// this is the method defined in wasm code
// you need to know what methods are defined in your source code
const addNumbers = wasm.instance.exports.addTwo;
// console.log(addNumbers);
const result = addNumbers(100, 50);
console.log(result);
} catch (e) {
console.log(e);
}
}
如果您可以在静态或公共文件夹中公开wasm文件,这样任何人都有可能获取它,那么您可以按照Yilmaz的建议,自己获取wasm模块。之后,您仍然可以使用由wasm-pack生成的包。init函数接受可选的模块参数,因此如果您执行
const buffer = await res.arrayBuffer();
然后您可以传递缓冲区ti-init函数,它不会自己尝试获取它。
还用wasm-pack命令的目标参数"进行实验;web";目标可能比"目标"工作得更好;nodejs";(不确定您是如何构建包的(
如果将wasm文件公开给公众是不好的,并且您希望在服务器端异常地运行它(例如仅在API中(,那么这将是一个更大的问题。