如何使用wasm-bindgen调用作为模块的JavaScript函数



我正试图使用Rust的Web3 JavaScript库,但我被卡住了。库的标准用法从以下开始:

// In Node.js use: const Web3 = require('web3');
let web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");

要导入的模块是一个构造函数,它还具有一些其他属性。我的Rust代码应该绑定这个API,看起来是这样的:

#[wasm_bindgen(module = "web3")]
extern "C" {
type Web3;
#[wasm_bindgen(constructor)]
fn new(_: &Provider) -> Web3;
type Provider;
static givenProvider: Provider;
}

其最终输出import { Web3, givenProvider } from 'web3';并尝试运行失败的new Web3(...)。它应该执行类似import * as Web3 from 'web3';的操作,运行new Web3(...)并引用Web3.givenProvider

如何让wasm-bindgen输出这样的代码?

编辑:原始答案是错误的。您可以导入使用wasm-bindgen定义的东西,它们合法的ES6。或者至少在ES6模块中可以使用相同的概念。他们称之为默认导出/导入。这有点尴尬,但导入它们的方法是使用js_name = "default"。像这样:

#[wasm_bindgen(module = "web3")]
extern "C" {
#[wasm_bindgen(js_name = "default")]
type Web3;
#[wasm_bindgen(constructor, js_class = "default")]
fn new(_: &Provider) -> Web3;
#[wasm_bindgen(static_method_of = Web3, getter, js_class = "default")]
fn givenProvider() -> Provider;
type Provider;
}

方法上需要js_class参数,它不记得Web3js_namedefault


旧的错误答案

您不能让wasm-bindgen生成这样的代码的原因是因为它不是合法的ES6。ECMAScript模块对所有内容都使用命名导出。Web3实际上是一个CommonJS模块,确实支持一个匿名导出。

几乎工作的原因是因为我使用的是webpack,而webpack允许您使用ES6语法导入CommonJS模块,尽管语义略有不同。

解决方案是制作一个小垫片,从ES6模块导出CommonJS模块:

export let Web3 = require('web3');

然后此绑定将起作用:

#[wasm_bindgen(module = "/src/web3-wrapper.js")]
extern "C" {
type Web3;
#[wasm_bindgen(constructor)]
fn new(_: &Provider) -> Web3;
#[wasm_bindgen(static_method_of = Web3, getter)]
fn givenProvider() -> Provider;
type Provider;
}

最新更新