When using the transform API with syntax lowering (e.g. for classes) or with keepNames (--keep-names), the code generated often look something like this:
const _Foo = class _Foo {
};
__name(_Foo, "Foo");
__publicField(_Foo, "prop", "value");
export let Foo = _Foo;
Playground link
Because the __publicField and __name aren't marked as pure (/* @__PURE__ */), even if _Foo is unused, bundlers are not able to assume it's safe to treeshake it. Should esbuild be prepending the /* @__PURE__ */ comments to __publicField and __name?
The __publicField and __name statements are holding a value on _Foo, which prevents it from being treeshaken if the exports are unused in bundlers.
I noticed for function expressions and keepNames, e.g. with export const foo = () => {}, esbuild is already transforming it to export const _foo = /* @__PURE__ */ __name(() => {}, "foo"). This has allowed esbuild to treeshake it if unused.
Perhaps something similar can be done for non-expressions and for the lowering code.