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

__name is not in scope if a class is stringified. #1438

Closed
yoshikiohshima opened this issue Jul 9, 2021 · 7 comments
Closed

__name is not in scope if a class is stringified. #1438

yoshikiohshima opened this issue Jul 9, 2021 · 7 comments

Comments

@yoshikiohshima
Copy link

yoshikiohshima commented Jul 9, 2021

Related to #1437, a function in code:

class Foo {
    foo() {
        let add = (e) => console.log(e);
       add("x");
   }
}

becomes:

var Foo = class {
  foo() {
    let add = /* @__PURE__ */ __name((e) => console.log(e), "add");
    add("x");
  }
};

when bundled with --bundle --keep-names --format=esm options.

However, __name function is not in the scope when the class is stringified by toString() and then eval()'ed again. An anonymous function like add above does not need to have .name property if it did not have one in code.

@navanshu
Copy link

navanshu commented Aug 5, 2021

You will have to set keep-names to false and __name won't show up in your final code and your program will run fine. If that is what you intentd.

__name beign there seems like a esbuild bug to me. since it has not been defined in the final output by esbuild

If you intent to use keep-names then __name, it is to wrap this function into some other function call. I even don't understand the use case for keep names, it might be a bug.

@evanw
Copy link
Owner

evanw commented Aug 5, 2021

However, __name function is not in the scope when the class is stringified by toString() and then eval()'ed again. An anonymous function like add above does not need to have .name property if it did not have one in code.

This scenario is not supported by esbuild. See https://esbuild.github.io/content-types/#function-tostring for more information.

@yoshikiohshima
Copy link
Author

Okay... It is unfortunate that in my particular use case, those classes and functions obey the rule of not having any references to external variables so that the combination of toString() and eval() is guaranteed to work. It this particular case, esbuild introduces new external references, which to me is non-semantics preserving transformation.. But I understand that for vast majority of cases, esbuild is doing really great job, and it does not have to address an issue in a particular case (which, incidentally, a live collaborative programming environment where that restricted JS code is sent over the network. I kind of like to demo it if there is a change ^^;)

@evanw
Copy link
Owner

evanw commented Oct 15, 2021

This is problematic in more cases than just --keep-names so changing how that feature is implemented is still a brittle solution and may randomly break in the future, since this is still an unsupported use case and esbuild uses helper functions for other things too. If you still want to use esbuild, you should instead build the source code in a separate build step and then insert it as a string into your code that needs the string.

Closing since this is an unsupported use case.

@evanw evanw closed this as completed Oct 15, 2021
@privatenumber
Copy link
Contributor

I understand this use-case is not supported, but wanted to share an unfortunate scenario where this is also problematic:
privatenumber/tsx#87

@yoshikiohshima
Copy link
Author

Thanks. it would be really great if esbuild does not add new globals and keep the semantics of original code in just a bit more strict sense.

@privatenumber
Copy link
Contributor

privatenumber commented Oct 11, 2022

This is problematic in playwright in addition to terser-webpack-plugin: privatenumber/tsx#113

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

No branches or pull requests

4 participants