Closed BendingBender closed 2 years ago
This package uses Function.toString()
to modify the function $asyncbind
:
https://github.com/MatAtBread/nodent-runtime/blob/master/runtime.js#L21
Then use new Function()
to return the modified function again.
The problem here is after this code being processed with esbuild's --keep-names
option, esbuild puts some __name()
to the original $asyncbind
function body, and new Function()
creates a pure environment that evaluates at the global scope where code can not find variables outer:
var __name = 1
new Function(`console.log(__name)`)() // ReferenceError: __name is not defined
// NOTE: try run this code in a closure, for example in a function(){}
The solution is either not relying on function string or not using --keep-names
.
Tried this out, without keepNames
option the build isn't broken any more. Thank you!
This package uses
Function.toString()
to modify the function$asyncbind
: https://github.com/MatAtBread/nodent-runtime/blob/master/runtime.js#L21 Then usenew Function()
to return the modified function again.
Libraries that do this are explicitly not supported: https://esbuild.github.io/content-types/#function-tostring. Libraries that do this will likely not work with esbuild, and may break with esbuild in the future even if they happen to work at the current moment. This is because esbuild relies on the ability to introduce helper functions for various things and relies on the ability to rename things within the bounds of JavaScript's scoping rules.
So disabling --keep-names
isn't really a solution even if it happens to work because may can break at any time in the future. It's fine if it works for you! But I just wanted to give you a heads up that doing this is brittle and may still not work. There is no straightforward way to fix this from esbuild's side. The way to get this to work robustly with esbuild would be for that library to change their build script to convert the function to a string ahead of time instead of calling toString()
at run-time.
Closing this issue because this is out of scope. Preserving the value of toString()
is explicitly unsupported.
Just for the record, disabling keepNames
only solved the immediate runtime error. The bundle was still broken after disabling this option. We solved the problem by removing the offending lib completely.
Hi, we have an Angular project and we use the
angular/cli@12.2.13
along with@angular-devkit/build-angular@12.2.13
to build a universal app. This internally usesesbuild@0.13.8
to minify the generated bundles.When we include a dependency that uses the
nodent-runtime@3.2.1
package, the build succeeds but the generated bundle then throws when executed with the error:ReferenceError: __name is not defined
.It seems to be related to how
nodent-runtime
works, which seems to stringify and evaluate a function viaFunction
constructor whose contents were previously annotated with Esbuild's__name
helper and this helper seems not to be in scope any more when this evaluation takes place.Here's the full error output:
node --version
: v16.11.1npm --version
: 8.1.4