Microsoft/TypeScript

Source map `mappings` is sometimes empty

Open

#52,005 opened on Dec 23, 2022

View on GitHub
 (1 comment) (1 reaction) (0 assignees)TypeScript (48,455 stars) (6,726 forks)batch import
BugDomain: Source MapsHelp Wanted

Description

Bug Report

🔎 Search Terms

source map empty mappings

🕗 Version & Regression Information

  • This is the behavior as far back as TypeScript 3.3

⏯ Playground Link

Playground link with relevant code

💻 Code

export type n = number

🙁 Actual behavior

The generated source map looks like this:

{
  "version": 3,
  "file": "input.js",
  "sourceRoot": "",
  "sources": [
    "input.tsx"
  ],
  "names": [],
  "mappings": "",
  "sourcesContent": [
    "export type n = number\n"
  ]
}

🙂 Expected behavior

I expected something like this instead:

{
  "version": 3,
  "file": "input.js",
  "sourceRoot": "",
  "sources": [
    "input.tsx"
  ],
  "names": [],
  "mappings": "AAAA",
  "sourcesContent": [
    "export type n = number\n"
  ]
}

The problem is that TypeScript generates an empty mappings value. This causes tools such as esbuild that process source maps to not carry through any mappings when the input is bundled with source maps enabled. The end user visible effect of this is a user using tsc to compile TypeScript to JavaScript, bundling the JavaScript with esbuild, and then being confused why there are intermediate build files in the final source map instead of the original TypeScript files. This was reported to me as a bug in esbuild (https://github.com/evanw/esbuild/issues/2767) but I think it should be considered a bug in TypeScript instead. My rationale:

  • The content in the sources array is only ever referenced by the "zero-based index into the sources list" in a mapping. So if there are no mappings, then there is no reference to the sources array for esbuild to carry forward, and the name in the sources array will never be included.

  • It would be incorrect for esbuild to assume that if there are no mappings but there is a single entry in the sources array, then esbuild should automatically generate a mapping from the start of the output code to the start of that single source. This is because esbuild doesn't have enough information to know whether the content of the source file is related to the code in the output or not. The code in the output could be entirely unrelated to the source file (one example scenario: https://github.com/evanw/esbuild/issues/2767#issuecomment-1364177552).

  • Arguably the module shim output that TypeScript generates even when the file is empty ("use strict", __esModule, etc.) should still be associated with the input source file in TypeScript's source map, since TypeScript is processing each file one-at-a-time so all code it generates relates to the input source file. It's ok for the mappings value to be empty if the output is empty (since there is nothing to map), but if the output is non-empty then I'd expect for mappings to also be non-empty.

I'm primarily reporting this for your awareness. You could also argue that the source map TypeScript generates should have an empty mappings value because none of the statements in the file made it into the final output, and the fact that the source file is missing from the final bundled source map is actually correct. If so, then feel free to close this issue.

Contributor guide

Source map `mappings` is sometimes empty · Microsoft/TypeScript#52005 | Good First Issue