我怎样才能调用一个 JavaScript 函数,它是一个带有 wasm-bindgen 的模块?
How can I call a JavaScript function that is a module with wasm-bindgen?
我正在尝试使用 Rust 的 Web3 JavaScript 库,但我被卡住了。库的标准用法以:
开头
// In Node.js use: const Web3 = require('web3');
let web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
您应该导入的模块是一个构造函数,它还有一些其他属性。我应该绑定此 API 的 Rust 代码如下所示:
#[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';
、运行ning new Web3(...)
和引用 Web3.givenProvider
.
的事情
如何让 wasm-bindgen 输出这样的代码?
EDIT: 原来的答案是错误的。您 可以 导入使用 wasm-bindgen
定义的东西,它们 是 合法的 ES6。或者至少在 ES6 模块中可以使用相同的概念。他们称他们为default exports/imports。有点别扭,但是导入它们的方法是使用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
参数,它不记得Web3
的js_name
是default
。
旧的,错误的答案:
您无法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;
}
我正在尝试使用 Rust 的 Web3 JavaScript 库,但我被卡住了。库的标准用法以:
开头// In Node.js use: const Web3 = require('web3');
let web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
您应该导入的模块是一个构造函数,它还有一些其他属性。我应该绑定此 API 的 Rust 代码如下所示:
#[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';
、运行ning new Web3(...)
和引用 Web3.givenProvider
.
如何让 wasm-bindgen 输出这样的代码?
EDIT: 原来的答案是错误的。您 可以 导入使用 wasm-bindgen
定义的东西,它们 是 合法的 ES6。或者至少在 ES6 模块中可以使用相同的概念。他们称他们为default exports/imports。有点别扭,但是导入它们的方法是使用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
参数,它不记得Web3
的js_name
是default
。
旧的,错误的答案:
您无法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;
}