wasm-bindgen icon indicating copy to clipboard operation
wasm-bindgen copied to clipboard

Deterministic Typescript Output

Open nickbabcock opened this issue 2 months ago • 6 comments

If wasm-bindgen deterministically output Typescript definitions, this would facilitate snapshot testing of emitted types, and add a layer of observability to know when things have changed.

Currently the output is not deterministic:

// lib.rs
mod bar;
mod foo;
// bar.s
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn b1() -> f64 {
    1.0
}
// foo.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn a1() -> f64 {
    1.0
}

A build and bind:

cargo build --target wasm32-unknown-unknown
wasm-bindgen # ...

Outputs a typescript definition of

export function a1(): number;
export function b1(): number;

To demonstrate the typescript definitions are not deterministic:

[profile.dev]
codegen-units = 1

The typescript output will now have the order flipped

export function b1(): number;
export function a1(): number;

My understanding is that the exports are explicitly not sorted

https://github.com/wasm-bindgen/wasm-bindgen/blob/ac51055a4c39fa0affe02f7b63fb1d4c9b3ddfaf/crates/cli-support/src/js/mod.rs#L4310-L4312

I’m not sure I follow the logic of sorting taking away control when the user doesn’t seem to have any control.

But perhaps there is a way to keep the current non-sort exports but then sort them for typescript purposes as a first pass?

I think it should be understood that a fully deterministic output for all wasm-bindgen targets should not be expected (ie: the wasm bindgen closure ID’s), but this would still allow snapshot tests to compare types up until a marker like InitInput

nickbabcock avatar Oct 14 '25 13:10 nickbabcock

Yes please. I was just about to file an issue that (at least for our use case) the output of 0.2.101 was still deterministic, but 0.2.102 broke it: https://github.com/torokati44/ruffle/actions/workflows/test_extension_dockerfile.yml We need deterministic builds so the Firefox extension we submit to the Mozilla add-on store passes manual reviews (don't even ask about it...). To be precise, both the WASM and .js output needs to be deterministic for this.

While this is an entirely blind guess, maybe https://github.com/wasm-bindgen/wasm-bindgen/pull/4650 was the PR that regressed this for us...?

torokati44 avatar Oct 19 '25 21:10 torokati44

See this previous correspondence (of many) about this, for example: https://github.com/wasm-bindgen/wasm-bindgen/pull/3851

torokati44 avatar Oct 19 '25 21:10 torokati44

(I also kinda wish there was some CI check for this around here, so determinism doesn't accidentally get lost from time to time... 🥺)

torokati44 avatar Oct 21 '25 10:10 torokati44

Just wanted to voice my support for this. A CI test would be great as well.

daxpedda avatar Nov 03 '25 07:11 daxpedda

@daxpedda did you have something more in mind than what PR https://github.com/wasm-bindgen/wasm-bindgen/pull/4738 adds?

nickbabcock avatar Nov 03 '25 13:11 nickbabcock

No. I will leave this to the experts to review.

daxpedda avatar Nov 03 '25 14:11 daxpedda