Skip to content

Consider emitting export {} in all ambiguous module output #38696

Description

In TypeScript 3.9, we started preserving export * for type-only modules. While this keeps our behavior more predictable long-term, this caused bundle-size regressions for teams combining Webpack and TypeScript (webpack/webpack#10889).

My understanding of the situation is that tools like Webpack use a similar disambiguation strategy as that of TypeScript to figure out whether a file is a module. Given that, when Webpack resolved to an empty file, it would bail out of certain optimizations thinking it was a global script file. In reality, all users using ts-loader's transpileModule mode were hitting this as well - it just turned out that the new behavior uncovered this behavior in a very large codebase.

We also discovered that we were not emitting "use strict" prologue directives even under alwaysStrict because we assumed that the output would be a module.

I also just discovered that import type { foo } from "bar"doesn't force an export {} in a module that does have values in it. That seems bad because this goes beyond special-casing for empty modules.

Here's the outcomes I could imagine:

  • TypeScript always emits an export {}. Is this really useful if the fix is already in-flight for Webpack?
  • TypeScript always emits an export {} under alwaysStrict when the output is empty (but then why does this matter?)
  • TypeScript keeps the current behavior.

Personally, my gut was to always emit the export {}; then I swung into thinking that emitting export {} on empty modules would be a weird vestigial behavior for empty modules. But then I realized that TypeScript doesn't emit any sort of module marker even when using import type, so I'm back to thinking we should always emit export {}.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

CommittedThe team has roadmapped this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions