Description
Currently, js_namespace
only accepts a Rust identifier (a syn::Ident
). Identifiers in JavaScript allow many more characters than Rust does, but that's not my point. It also means that you can't specify that a function or class (for constructors) belongs to a nested namespace (i.e. foo.bar.baz
).
WebIDL namespaces have been discussed in issue #253 and js_namespace
was implemented in #678, but the focus in these threads was on WebIDL, and "the webidl grammar does not allow nested namespaces". But do we only care about WebIDL or do we want to make wasm_bindgen
usable for generating bindings to general JavaScript code? I think the latter, right?
Well in JavaScript packages, namespaces are not incredibly common and nested namespaces are definitely quite rare, but they do happen. JavaScript doesn't really have namespaces as a built-in concept, but people still make namespaces out of regular objects.
An example of a JavaScript project using nested namespaces (I admit I had to search for it, it's definitely not as common as I thought) is the game engine Phaser. When you want to crate a physics entity in Phaser, you call new Phaser.Physics.Box2D.Body(...)
. As far as I can tell, it's impossible to write an idiomatic wasm_bindgen
binding for that new Phaser.Physics.Box2D.Body(...)
call.
I see 2 possible ways to fix that:
-
We could allow strings in the
js_namespace = ...
attribute, and then parse that string to see if it contains dots. Then we could treat those dot-separated identifiers as nested namespaces, and make both constructors and static methods operate on the right JS object. -
We could allow some form of modules/namespaces inside
wasm_bindgen
blocks. These would represent both Rust modules (in the generated Rust bindings) and JS namespaces (in the generated wasm/JS glue code). If we do this, I think it may be slightly more ergonomic to writewasm_bindgen
glue code for JS code with (potentially nested) namespaces, but I also think this would be a lot of work.
What do you think? Given how uncommon nested namespaces are, and given that namespaces are not a JavaScript language construct but rather a way in which some people use JS objects, should we even fix this? If so, which of these 2 fixes seems like the way to go? Or should we do something else entirely? I think I could implement the first fix myself, I don't think I can do the 2nd.