-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Import "new" becomes "_new" #4317
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
Comments
The underlying problem is that WBG currently escapes(?) keywords by prepending an underscore. This behavior is just completely broken. The only reason we have it is that not doing it would generate syntactically incorrect JS. The proper fix should have been to either never allow JS keywords as identifiers and make the proc macro error, or to handle keyword identifiers properly in JS. Yes, it turns out, JS can export values as keyword identifiers without issue. Example: function foo() {}
export { foo as class, foo as new, foo as function } For imports, the situation is different. If the imported value is NOT namespaced, then it cannot be a keyword. E.g. the following makes no sense: #[wasm_bindgen]
extern "C" {
// It's impossible to have a variable called "class" in JS. This binding cannot work. Never.
#[wasm_bindgen]
fn class();
} However, things change when we talk about namespaced values. Then only the first identifier of the namespace cannot be a keyword. The rest is fair game. Example: // This is completely fine. The function call `not_a_keyword.class.new.var.function()` is valid JS.
#[wasm_bindgenjs_namespace = ["not_a_keyword", "class", "new", "var"])]
extern "C" {
#[wasm_bindgen]
fn function();
} So my suggested course of action would be to properly fix keywords for imports now, and discuss how we want to handle exports later. |
I was talking about how this issue was caused. Internally, in WBG the same code caused the same issue: wasm-bindgen/crates/macro-support/src/parser.rs Lines 22 to 45 in 94b2dc6
#3930 implemented a way to skip certain keywords, in that case default . new is in that list as well.
Or is there some other part of the code that is responsible for doing the renaming to
Agreed. I want to note that this is actually a breaking change. But we have historically made the same kind of breaking change already in #3930, even if that was about exports and this is about imports. I'm not very concerned about the breaking change because I'm predicting that nobody actually relies on such subtle and unintended behavior. But I might be wrong! |
These keywords are "never allowed as identifiers" according to the ECMAScript language specification. But it seems browsers don't care so much (or Tauri, unfortunately for me!). We don't want to generate invalid ECMAScript. Though I suggest the following logic:
Nothing is ever escaped. Keywords are only valid inside namespaces on web. Methods are treated the same as other functions. I have had a go at fixing this myself... but I went down several rabbit holes and got lost. I probably also broke exports. I'm happy to help but I will need time to understand the code better (and github - it's my first time). |
I am trying to import
window.__TAURI__.menu.Menu.new
from Tauri.The generated JS is:
new
has become_new
, which does not exist. Usingjs_name = "new"
does not affect the generated JS. I have made an ugly workaround by aliasing_new
tonew
.Presumably this behaviour is deliberate because
new
is a JS keyword. However, it is also a valid function name ("valid" != "good").Would it be possible to force the
js_name
to be retained, even for keywords? Maybe something likeforce_js_name = true
to avoid breaking any existing code that relies on this? I have browsed around the code a bit but I can't find where this substitution is made. Are other keywords treated similarly?Alternatively, it would be useful if the guide mentioned this behaviour. It took me ages to figure out what was going on. I can have a go at making that change myself if needed.
The text was updated successfully, but these errors were encountered: