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

Transform produces invalid code for sources containing direct eval #2761

Closed
micschro opened this issue Dec 20, 2022 · 1 comment
Closed

Transform produces invalid code for sources containing direct eval #2761

micschro opened this issue Dec 20, 2022 · 1 comment

Comments

@micschro
Copy link

When this code

// source
if (true) { 
  function foo () {};
  eval(''); 
}

is transformed with default settings in esbuild 0.16.10, esbuild produces the following invalid output

// transformed
if (true) {
  let foo = function() {
  };
  var foo = foo;
  ;
  eval("");
}

=> Identifier 'foo' has already been declared

To reproduce, just call the transform API like this:

// index.js
console.log(require('esbuild').transformSync(`if (true) { function foo () {}; eval(''); }`).code)

I'm aware that direct eval should be avoided, but esbuild still should be able to produce valid output when it is used in the sources.

@evanw
Copy link
Owner

evanw commented Dec 23, 2022

The reason why esbuild does this is because function hoisting semantics depends on strict mode. If this code is followed by console.log(foo) and evaluated, it will print foo in non-strict mode but it will throw an error in strict mode. The transformation that esbuild does here is intended to preserve the original semantics of the input (which was in non-strict mode) even when the output is evaluated in strict mode.

It might be impossible to preserve the original semantics of the input like this while also preserving the names of these symbols for direct eval. So perhaps the answer here is to not do this transformation when direct eval is present. This means that direct eval will be able to reference foo but the final code may end up behaving differently from the original code since the original function hoisting semantics were not preserved.

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

2 participants