Skip to content

Fill out metafile export names in iife mode, or provide way to get exported names in non-ESM mode #3607

@jakebailey

Description

@jakebailey

Right now, TypeScript's bundle uses --format=iife --global-name=ts with a footer, resulting in:

var ts = (() => {
  // ...
  return ts_exports2;
})();
if (typeof module !== undefined && module.exports) {
  module.exports = ts;
}

This helped us remain compatible with our old bundles pre-5.0, which worked similarly to the above but with the old namespace object.

In microsoft/TypeScript#57133, I'm trying to use the same 0 && (module.exports = { foo, bar, baz }); trick that esbuild does to "annotate" the exports for Node, as our bundle is silently broken for anyone trying an ESM namespace import. If were were using --format=cjs --platform-node (along with export * instead of export =), then esbuild would handle this for us, but in order to keep our format, we can't do that.

--metafile does not fill in the export info when using --iife (or even cjs; #3110, #3281). This means that in order to do the same annotation trick, I need some other way to get the names. At the moment, I'm making our build import the bundle and read the list of names, which I'd prefer not to do.

Is there any way that --metafile could provide a list of exported names in --format=iife mode, as it does in --format=esm? I understand that it could be argued that the only "export" is the global name (if provided), but I'm looking for any way for me to statically reproduce the export annotation trick. It doesn't need to be the exports prop on metafile at all; I know this is a bit of an "XY problem" scenario.

The closest thing I've gotten is to run esbuild a second time but emit ESM, then use only the metafile and throw away the output, but that turns out to require code changes in TypeScript to eliminate export = ts and seems to be a bit slower than just importing the (almost) final bundle.

It could be the case that this is just a pure dupe of #3281 / #3110, of course (in which case feel free to close). Or, you'll come up with some other idea 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions