Skip to content

improve keepNames behavior for profiling tools#4296

Open
sophiebits wants to merge 1 commit intoevanw:mainfrom
sophiebits:sophiebits/keep-names-2
Open

improve keepNames behavior for profiling tools#4296
sophiebits wants to merge 1 commit intoevanw:mainfrom
sophiebits:sophiebits/keep-names-2

Conversation

@sophiebits
Copy link
Copy Markdown

@sophiebits sophiebits commented Oct 6, 2025

In my esbuild app with keepNames: true, minify: false I noticed that for declarations let foo = function() {} the function shows in V8 profiles as anonymous, whereas it works fine for keepNames: false, minify: false. This is due to the transformation to let foo = __name(function() {}, 'foo') which prevents the NamedEvaluation on the anonymous function which typically happens natively (eg: https://tc39.es/ecma262/#sec-variable-statement-runtime-semantics-evaluation for VariableDeclaration).

Evidently V8 keeps an internal idea of the function name distinct from the .name property. To work around this, we transform these instead to let foo = __firstValue({ foo: function() {} }) which takes advantage of the name assignment in https://tc39.es/ecma262/#sec-runtime-semantics-propertydefinitionevaluation. With this fix, these functions show names correctly in the Chrome profiler.

In my esbuild app with keepNames: true, minify: false I noticed that for declarations `let foo = function() {}` the function shows in V8 profiles as anonymous. This is due to the transformation to `let foo = __name(function() {}, 'foo')` which prevents the NamedEvaluation on the anonymous function which typically happens natively (eg: https://tc39.es/ecma262/#sec-variable-statement-runtime-semantics-evaluation for VariableDeclaration).

Evidently V8 keeps an internal idea of the function name distinct from the .name property. To work around this, we transform these instead to `let foo = __firstValue({ foo: function() {} })` which takes advantage of the name assignment in https://tc39.es/ecma262/#sec-runtime-semantics-propertydefinitionevaluation. With this fix, these functions show names correctly in the Chrome profiler.

// Update the "name" property on the function or class for "--keep-names"
export var __name = (target, value) => __defProp(target, 'name', { value, configurable: true })
export var __firstValue = (obj) => { for (var k in obj) { if (__hasOwnProp.call(obj, k)) return obj[k]; } }
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not sure if esbuild intends to support mutating Object.prototype; if not, can remove the __hasOwnProp check)

@sophiebits
Copy link
Copy Markdown
Author

@evanw I would appreciate a review here if you have some time 🙏

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

Successfully merging this pull request may close these issues.

1 participant