We have this old open source project SlickGrid used by thousand of users, I'm slowly rewriting the code to support 3 build formats ifie, cjs and esm and I'm using this plugin esbuild-plugin-ifdef to execute conditional code while building for ESM. The project was originally built as iife and I still want to support that standalone format, by having a global name of Slick on the window object, while also produce ESM build
Repro
Here's a https://esbuild.github.io/try repro
Code repro
// index.ts
import { Utils as Utils_ } from './utils.ts'; // dropped in iife by custom plugin of mine
//#ifdef ESM_ONLY
window.Slick = null; // enabled only for ESM build
//#endif
// use this ternary as a trick so that I can build for both iife and esm
// for iife, this is great I got no dead code because I have a custom plugin that removes all imports
// but for esm build I get window.Slick dead code not being tree shaked
const Utils = window.Slick ? Slick.Utils : Utils_;
// use utils
Utils.createDomElement('div', { className: 'header' });
// utils.ts
export function createDomElement(tagName, elementOptions) {
const elm = document.createElement(tagName);
if (elementOptions) {
Object.keys(elementOptions).forEach((elmOptionKey) => {
const elmValue = elementOptions[elmOptionKey];
if (typeof elmValue === 'object') {
Object.assign(elm[elmOptionKey], elmValue);
} else {
elm[elmOptionKey] = (elementOptions)[elmOptionKey];
}
});
}
return elm;
}
export const Utils = {
createDomElement
}
when running with this config
{
bundle: true,
minifySyntax: true,
format: 'esm',
treeShaking: true,
outfile: 'index.js'
}
Expectation
I was expecting all window.Slick code to be dropped with tree skaking process (even with /* @__PURE__ */ it makes no difference)
So I was expecting this code
import { Utils as Utils_ } from './utils.ts'; // dropped in iife by custom plugin of mine
window.Slick = null; // for ESM only
const Utils = window.Slick ? Slick.Utils : Utils_;
Utils.createDomElement('div', { className: 'header' });
to be transformed to this code
import { Utils } from './utils.ts';
Utils.createDomElement('div', { className: 'header' });
but in reality the output is
window.Slick = null;
var Utils2 = (
window.Slick ? Slick.Utils : Utils
);
Utils2.createDomElement("div", { className: "header" });
Technically speaking window.Slick is null so the first ternary case window.Slick ? Slick.Utils will never be reached, so why isn't it removed? Is there another way to get it removed somehow?
For now I can live with what esbuild creates but it would be nice if I could somehow delete this unreachable code for my ESM output and lower my build size a little. If it's not possible, I can live with what I have about 100 lines like this, and everything is working fine (it's just dead code that's all).
We have this old open source project SlickGrid used by thousand of users, I'm slowly rewriting the code to support 3 build formats
ifie,cjsandesmand I'm using this plugin esbuild-plugin-ifdef to execute conditional code while building for ESM. The project was originally built asiifeand I still want to support that standalone format, by having a global name ofSlickon the window object, while also produce ESM buildRepro
Here's a https://esbuild.github.io/try repro
Code repro
when running with this config
Expectation
I was expecting all
window.Slickcode to be dropped with tree skaking process (even with/* @__PURE__ */it makes no difference)So I was expecting this code
to be transformed to this code
but in reality the output is
Technically speaking
window.Slickis null so the first ternary casewindow.Slick ? Slick.Utilswill never be reached, so why isn't it removed? Is there another way to get it removed somehow?For now I can live with what esbuild creates but it would be nice if I could somehow delete this unreachable code for my ESM output and lower my build size a little. If it's not possible, I can live with what I have about 100 lines like this, and everything is working fine (it's just dead code that's all).