Как я могу вызвать функцию JavaScript, которая является модулем с wasm-bindgen?

Я пытаюсь использовать библиотеку JavaScript Web3 от Rust, и я застрял. Стандартное использование библиотеки начинается с:

// 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 выводить такой код?


person Echo Nolan    schedule 16.11.2020    source источник


Ответы (1)


ИЗМЕНИТЬ: исходный ответ неверен. Вы можете импортировать подобные вещи с помощью 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 в методах, он не помнит, что js_name Web3 это default.


Старый неправильный ответ:

Причина, по которой вы не можете заставить wasm-bindgen сгенерировать такой код, заключается в том, что это не законно для ES6. Модули ECMAScript используют именованный экспорт для всего. Web3 на самом деле является модулем CommonJS, и те делают поддерживают единственный анонимный экспорт.

Причина, по которой он почти работает, заключается в том, что я использовал webpack, а webpack позволяет импортировать модули CommonJS с использованием синтаксиса ES6, хотя семантика немного отличается.

Решение состоит в том, чтобы сделать небольшую прокладку, экспортируя модуль CommonJS из модуля ES6:

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;
}
person Echo Nolan    schedule 21.11.2020