Skip to content

Nested namespaces #951

Open
Open
@michiel-de-muynck

Description

@michiel-de-muynck

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:

  1. 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.

  2. 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 write wasm_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions