Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

map typescript default module #2064

Closed
ctaggart opened this issue Mar 31, 2020 · 7 comments
Closed

map typescript default module #2064

ctaggart opened this issue Mar 31, 2020 · 7 comments
Labels

Comments

@ctaggart
Copy link
Contributor

I'm having difficulty mapping the typescript module. The generated code creates:

const { ts } = require(String.raw`typescript`);

but I think it will work if it creates:

const ts = require(String.raw`typescript`);

I found #1006 fixed by #1106, but I couldn't get it to work. Here is lib.rs:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn greet() {
    log("hello node");
    log(&ts.getNodeMajorVersion());
    // log(&version);
}

// https://rustwasm.github.io/docs/wasm-bindgen/examples/console-log.html
#[wasm_bindgen]
extern {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

// https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/module.html
// default pr https://github.com/rustwasm/wasm-bindgen/pull/1106/files
#[wasm_bindgen(module = "typescript")]
extern {
    
    #[wasm_bindgen(js_name = default)]
    type Ts;
    static ts: Ts;

    #[wasm_bindgen(method)]
    fn getNodeMajorVersion(this: &Ts) -> String;

    // static version: String;
}

I've tried #[wasm_bindgen(js_name = default)] on static ts: Ts as well.

@Pauan
Copy link
Contributor

Pauan commented Mar 31, 2020

You need to bind it like this:

#[wasm_bindgen(module = "typescript")]
extern {
    type Ts;

    #[wasm_bindgen(js_name = default)]
    static ts: Ts;

    #[wasm_bindgen(method)]
    fn getNodeMajorVersion(this: &Ts) -> String;

    // static version: String;
}

@Pauan Pauan closed this as completed Mar 31, 2020
@Pauan
Copy link
Contributor

Pauan commented Mar 31, 2020

Hmmm, actually, after checking the generated code, that looks for a default export.

I don't think we actually have any way to bind to the actual module right now.

@Pauan Pauan reopened this Mar 31, 2020
@Pauan
Copy link
Contributor

Pauan commented Mar 31, 2020

However, if you only need to bind to the properties (not the module itself), you can do this:

#[wasm_bindgen(module = "typescript")]
extern {
    fn getNodeMajorVersion() -> String;
}

That should work fine.

@ctaggart
Copy link
Contributor Author

I do want to build to be able to bind to the module itself, access ts.getNodeMajorVersion() as well as ts.version.

That suggested binding leads to this error:

Camerons-MacBook-Pro:wasm-game-of-life cameron$ ./run.sh 
hello node
buffer.js:693
    throw new ERR_INVALID_ARG_TYPE(
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type number
    at Function.byteLength (buffer.js:693:11)
    at passStringToWasm0 (/Users/cameron/tmp/wasm-game-of-life/pkg/wasm_game_of_life.js:41:24)
    at module.exports.__wbg_getNodeMajorVersion_13fd2c79e63df52c (/Users/cameron/tmp/wasm-game-of-life/pkg/wasm_game_of_life.js:62:16)
    at wasm-function[17]:26
    at wasm-function[40]:1
    at Object.<anonymous> (/Users/cameron/tmp/wasm-game-of-life/main.js:7:5)
    at Module._compile (internal/modules/cjs/loader.js:936:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
    at Module.load (internal/modules/cjs/loader.js:790:32)
    at Function.Module._load (internal/modules/cjs/loader.js:703:12)

wasm_game_of_life.js:62 is the line with passStringToWasm0 in:

module.exports.__wbg_getNodeMajorVersion_13fd2c79e63df52c = function(arg0) {
    var ret = getNodeMajorVersion();
    var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    var len0 = WASM_VECTOR_LEN;
    getInt32Memory0()[arg0 / 4 + 1] = len0;
    getInt32Memory0()[arg0 / 4 + 0] = ptr0;
};

@ctaggart
Copy link
Contributor Author

@Pauan
Copy link
Contributor

Pauan commented Apr 1, 2020

@ctaggart The problem with your code is that getNodeMajorVersion() returns undefined or a number, not a string. That's why you're getting that error.

You don't need to bind to the typescript module itself, you can just bind to the things exported by it:

#[wasm_bindgen(module = "typescript")]
extern {
    fn getNodeMajorVersion() -> Option<u32>;

    static version: String;
}

@Pauan Pauan closed this as completed Apr 1, 2020
@ctaggart
Copy link
Contributor Author

ctaggart commented Apr 1, 2020

Works great @Pauan, thanks!

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn greet() {
    log("hello node");
    if let Some(major_node_version) = getNodeMajorVersion() {
        log(&format!("Node major version: {}", &major_node_version));
    }
    log(&format!("TypeScript version: {}", &version.to_string()));
}

// https://rustwasm.github.io/docs/wasm-bindgen/examples/console-log.html
#[wasm_bindgen]
extern {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

// https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/module.html
#[wasm_bindgen(module = "typescript")]
extern {
    fn getNodeMajorVersion() -> Option<u32>;
    static version: String;
}

greet() prints:

hello node
Node major version: 12
TypeScript version: 3.8.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants