-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Description
It seems like esbuild generally inlines IIFEs, but at least sometimes this does not seem to be happening. One example:
// Input
function x(): string {
console.log('x');
return 'x';
}
function y(): void {
const cb = () => {
console.log(x());
};
return cb();
}
y();// Current output
function x() {
return console.log("x"), "x";
}
function y() {
// Unnecessary `return` and IIFE
return (() => {
console.log(x());
})();
}
y();// Expected output
function x() {
return console.log("x"), "x";
}
function y() {
console.log(x());
}
y();Ideally, this should be able to further inline the only calls of x and y into:
// Ideal output
console.log(console.log("x"), "x");This is may be related in terms of function call inline, but is potentially more involved than just inlining an IIFE.
I ran into this today when attempting to conditionally wrap a function based on a --define value like so:
declare global {
var isDebug: boolean | undefined;
}
function doSomething(): void {
const callback = () => {
console.log('something');
};
if (isDebug) {
callWithDebugInfo(callback);
} else {
callback();
}
}
function callWithDebugInfo(callback: () => void): void {
setDebugInfo({/* ... */});
try {
callback();
} finally {
removeDebugInfo({/* ... */});
}
}esbuild is able to correctly tree-shake callWithDebugInfo with --define:isDebug=false, but this leaves an extra IIFE in the production optimization (unable to properly inline callback()), which is a cost I'd prefer not to pay for this debug feature.
michael-small
Metadata
Metadata
Assignees
Labels
No labels