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

ReferenceError: __name is not defined #1031

Closed
sto3psl opened this issue Mar 22, 2021 · 14 comments
Closed

ReferenceError: __name is not defined #1031

sto3psl opened this issue Mar 22, 2021 · 14 comments

Comments

@sto3psl
Copy link

sto3psl commented Mar 22, 2021

Hi there, first of all, thanks for all the hard work you put into esbuild, it's awesome!

I have an issue with the keepNames option of esbuild. First of all some info about versions. I'm using esbuild through Vite.

  • Vite Version: 2.1.2
  • esbuild version: 0.9.6

What's happening is, that esbuild is bundling a file, where it renames the functions and then adds a __name function like so:

// source
function init () {}

// output
function init3 () {}
__name(init3, 'init')

The problem is, that the __name function never gets defined in my module, which is causing the error ReferenceError: __name is not defined in the browser.

The actual input and output files are in this Gist: https://gist.github.com/sto3psl/8bca4562096050559ec51544483edc33

Here are the references with the above mentioned init function:

There are a bunch of __name references in the esbuild output but no definition of said function. I'm not sure what's happening but if it helps, this file does run in a Worker. If for some optimization reasons __name is defined on window or in the main thread in general, it isn't accessible in the Worker.

I'd appreciate any help and am not sure if this is a Vite or esbuild problem.

This is the Vite commit that introduced the keepNames behaviour: vitejs/vite@b5cd8c8

@flunderpero
Copy link

This comes up in other places too, like #607

@evanw
Copy link
Owner

evanw commented Mar 22, 2021

The actual input and output files are in this Gist: https://gist.github.com/sto3psl/8bca4562096050559ec51544483edc33

This doesn't look like output from esbuild. The code generator doesn't generate blank lines like that. So I assume something else is happening after esbuild runs that is messing this up.

Another thing to note is that esbuild is not designed to preserve the value of Function.prototype.toString(). It assumes that the JavaScript it builds follows the normal scoping rules. So the __name helper (along with all of the other helpers that esbuild uses) is defined once at the top-level scope instead of being re-defined in every single function scope.

This means you can't just call .toString() on a function and eval it somewhere else to relocate it. Just disabling the keepNames option is not a robust approach because other helpers such as __publicField for class fields will also behave similarly. Although you could potentially ask Vite to provide the option to disable this to unblock you.

So if you're using code inside a worker make sure you're not calling .toString() on a function. Instead you should be bundling the code for the worker into another entry point and either including that bundled code as a string in your final output, or referencing the bundled file via URL in the worker constructor.

@sto3psl
Copy link
Author

sto3psl commented Mar 22, 2021

Do you have an idea what the actual problem is and if it's an issue with Vite? I don't call .toString() anywhere but looking at my project the worker code is loaded as a Blob from Vite.

The output I pasted came out of the sources panel of Firefox DevTools, so that might explain the blank lines.

After running esbuild isolated over the specified file, the first two lines are

var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", {value, configurable: true});

This is what I'd expect and maybe Vite removes them for some reason?

I'm a little lost here but I guess I'm going to open an issue with Vite.

@sto3psl
Copy link
Author

sto3psl commented Mar 22, 2021

I just checked the library I'm using and how it creates the Worker. Turns out this is the code:

export function makeWorkerBlob(func: Function, deps: Function[]) {
  let str = "'use strict';\n\n" + makeWorkerString(deps);
  str += "\n\n\nself.func = " + func.toString() + ";";
  str += "\n\n\nself.onmessage = " + onmessage.toString() + ";";
  // console.log(str);
  return new Blob([str], { type: "application/javascript" });
}

To summarize esbuild does the correct thing and deduplicates __name and because of the .toString() this of course won't end up in the worker scope.

Now I need to figure out, how I can fix this in the library.

Thanks anyway @evanw, you pointed me in the right direction.

@flunderpero
Copy link

I really support @evanw point of view on this.
But there seem to be some libraries out there (canvas-confetti being another one) that generally use workers that way and those libraries fail with esbuild. As @evanw pointed out it is not only keepNames that could potentially break the code.
I don't have an idea on how to fix this or if it's even worth fixing it. Not being able to bundle (quite popular) libraries is at least surprising.

@evanw
Copy link
Owner

evanw commented Mar 23, 2021

I think the most straightforward solution here is that Vite should not have this option force-enabled. I left a comment about this here: vitejs/vite#2376 (comment).

@sto3psl
Copy link
Author

sto3psl commented Mar 24, 2021

Thanks for your help with this @evanw!

@itsthekeming
Copy link

itsthekeming commented Mar 26, 2021

So it's probably an issue with Vite? I am encountering this issue using Vite and @react-three/drei's useGLTF hook.

The hook loads a draco decompressor from a static url that I think uses a worker. I have similar code in my browser dev-tools as @sto3psl, and the same __name is not defined error for each node from my loaded GLTF file that draco tries to decompress.

I'm not super familiar with the intricacies of web workers. I did set keepNames in my Vite config to false but the issue persists.

EDIT: I was able to fix it by rolling back Vite v2.0.5. The culprit is v2.1.0+.

@itsthekeming
Copy link

Vite just merged pull request #2742 that fixes this issue, so this can probably be closed.

@evanw
Copy link
Owner

evanw commented Mar 29, 2021

Thanks for the update. Closing as this will be fixed in the next Vite release.

@lixiaofa
Copy link

lixiaofa commented Jul 4, 2023

@evanw @sto3psl
Have you solved it? I also encountered this problem, In CICD. local is OK.
image
https://github.com/lixiaofa/fast-plus/actions/runs/5443372337/jobs/9900013548

@Fuphoenixes
Copy link

@evanw @sto3psl 你解决了吗?我也遇到这个问题,在CICD中。本地就可以了。https://github.com/lixiaofa/fast-plus/actions/runs/5443372337/jobs/9900013548 图像

你解决了吗?我和遇到了一样的问题

@Mike-Bell
Copy link

another place where this comes up (currently): microsoft/onnxruntime#18673

@Maxim-Mazurok
Copy link

Maxim-Mazurok commented Feb 25, 2024

I'm having this error inside of await page.evaluate(async () => {...} code for puppeteer. It adds __name to my arrow function for some reason

Never mind, found the issue: 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

8 participants