由于“初始化前无法访问‘__wbindgen_throw’”错误,无法使用 web-assembly rust impl
Can not use web-assembly rust impl because of 'Cannot access '__wbindgen_throw' before initialization' error
我正在尝试向我的项目中添加一些网络程序集。一开始我创建了一个简单的方法来检查我的 webpack 是否运行良好以及我可以使用我的 .wasm
模块。所以我创建了这样的东西:
#[wasm_bindgen]
pub fn return_char() -> char {
return 'a';
}
然后我在我的网络组件的构造函数中使用了这个(只是为了检查是否一切正常):
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
console.log(return_char());
}
这按预期工作,我在我的网络应用程序控制台中看到 'a'
:
然后当我看到一切正常时,我创建了带有实现的结构:
#[wasm_bindgen]
pub struct Test {
value: char
}
#[wasm_bindgen]
impl Test {
pub fn new() -> Test {
let value: char = 'a';
Test {
value
}
}
pub fn value(&self) -> char {
self.value
}
pub fn change_value(&mut self) {
self.value = 'b';
}
}
然后我在同一个 Web 组件 class 构造函数中添加 Test
的创建实例,并调用此 Test
实现的方法。我认为我应该在我的控制台中看到 'a'
和 'b'
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
const test: Test = Test.new();
console.log(test.value());
test.change_value();
console.log(test.value());
}
但这并没有发生,我只看到了这个错误:
Uncaught (in promise) ReferenceError: Cannot access '__wbindgen_throw' before initialization at Module.__wbindgen_throw (calculator_engine_bg.js:5)
我不知道为什么会出现此错误以及如何解决此问题。也许我的 webpack.config.js
有问题?
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
experiments: {
asyncWebAssembly: true
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
include: [path.resolve(__dirname, 'src')],
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
},
plugins: [
new HTMLWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html',
}),
],
};
GitHub 重现所需代码最少的存储库:webpack-web-assembly-rust-impl-bug
webpack version: 5.0.0-beta.26
因此,正如 sokra 在我创建的 issue 下的回答中提到的那样。我应该使用 experiments.syncWebAssembly
而不是 experiments.asyncWebAssembly
。如果我使用这个 experiments.syncWebAssembly
我必须添加额外的文件,它将异步加载 index.ts
文件。
webpack.config.js
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: './src/bootstrap.ts', // !! <- change path to bootstrap.ts
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
experiments: {
syncWebAssembly: true // !! <- use syncWebAssembly instead of asyncWebAssembly
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
include: [path.resolve(__dirname, 'src')],
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
},
plugins: [
new HTMLWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html',
}),
],
};
bootstrap.ts
import('./index').catch(e => console.error('Error importing `index.js`:', e))
您可以在这里找到完整的解决方案:: webpack-web-assembly-rust-impl-bug
我正在尝试向我的项目中添加一些网络程序集。一开始我创建了一个简单的方法来检查我的 webpack 是否运行良好以及我可以使用我的 .wasm
模块。所以我创建了这样的东西:
#[wasm_bindgen]
pub fn return_char() -> char {
return 'a';
}
然后我在我的网络组件的构造函数中使用了这个(只是为了检查是否一切正常):
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
console.log(return_char());
}
这按预期工作,我在我的网络应用程序控制台中看到 'a'
:
然后当我看到一切正常时,我创建了带有实现的结构:
#[wasm_bindgen]
pub struct Test {
value: char
}
#[wasm_bindgen]
impl Test {
pub fn new() -> Test {
let value: char = 'a';
Test {
value
}
}
pub fn value(&self) -> char {
self.value
}
pub fn change_value(&mut self) {
self.value = 'b';
}
}
然后我在同一个 Web 组件 class 构造函数中添加 Test
的创建实例,并调用此 Test
实现的方法。我认为我应该在我的控制台中看到 'a'
和 'b'
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
const test: Test = Test.new();
console.log(test.value());
test.change_value();
console.log(test.value());
}
但这并没有发生,我只看到了这个错误:
Uncaught (in promise) ReferenceError: Cannot access '__wbindgen_throw' before initialization at Module.__wbindgen_throw (calculator_engine_bg.js:5)
我不知道为什么会出现此错误以及如何解决此问题。也许我的 webpack.config.js
有问题?
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
experiments: {
asyncWebAssembly: true
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
include: [path.resolve(__dirname, 'src')],
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
},
plugins: [
new HTMLWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html',
}),
],
};
GitHub 重现所需代码最少的存储库:webpack-web-assembly-rust-impl-bug
webpack version: 5.0.0-beta.26
因此,正如 sokra 在我创建的 issue 下的回答中提到的那样。我应该使用 experiments.syncWebAssembly
而不是 experiments.asyncWebAssembly
。如果我使用这个 experiments.syncWebAssembly
我必须添加额外的文件,它将异步加载 index.ts
文件。
webpack.config.js
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: './src/bootstrap.ts', // !! <- change path to bootstrap.ts
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
experiments: {
syncWebAssembly: true // !! <- use syncWebAssembly instead of asyncWebAssembly
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
include: [path.resolve(__dirname, 'src')],
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
},
plugins: [
new HTMLWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html',
}),
],
};
bootstrap.ts
import('./index').catch(e => console.error('Error importing `index.js`:', e))
您可以在这里找到完整的解决方案:: webpack-web-assembly-rust-impl-bug