Skip to content

Commit

Permalink
fix #3144: fill in null entries in source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jun 10, 2023
1 parent a08a7d9 commit e2993c0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

* Fill in `null` entries in input source maps ([#3144](https://github.com/evanw/esbuild/issues/3144))

If esbuild bundles input files with source maps and those source maps contain a `sourcesContent` array with `null` entries, esbuild previously copied those `null` entries over to the output source map. With this release, esbuild will now attempt to fill in those `null` entries by looking for a file on the file system with the corresponding name from the `sources` array. This matches esbuild's existing behavior that automatically generates the `sourcesContent` array from the file system if the entire `sourcesContent` array is missing.

## 0.18.0

**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.17.0` or `~0.17.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.
Expand Down
42 changes: 26 additions & 16 deletions internal/bundler/bundler.go
Expand Up @@ -480,23 +480,33 @@ func parseFile(args parseArgs) {
}
}

// If "sourcesContent" isn't present, try filling it in using the file system
if sourceMap != nil && sourceMap.SourcesContent == nil && !args.options.ExcludeSourcesContent {
for _, source := range sourceMap.Sources {
var absPath string
if args.fs.IsAbs(source) {
absPath = source
} else if path.Namespace == "file" {
absPath = args.fs.Join(args.fs.Dir(path.Text), source)
} else {
sourceMap.SourcesContent = append(sourceMap.SourcesContent, sourcemap.SourceContent{})
continue
}
var sourceContent sourcemap.SourceContent
if contents, err, _ := args.caches.FSCache.ReadFile(args.fs, absPath); err == nil {
sourceContent.Value = helpers.StringToUTF16(contents)
// If "sourcesContent" entries aren't present, try filling them in
// using the file system. This includes both generating the entire
// "sourcesContent" array if it's absent as well as filling in
// individual null entries in the array if the array is present.
if sourceMap != nil && !args.options.ExcludeSourcesContent {
// Make sure "sourcesContent" is big enough
if len(sourceMap.SourcesContent) < len(sourceMap.Sources) {
slice := make([]sourcemap.SourceContent, len(sourceMap.Sources))
copy(slice, sourceMap.SourcesContent)
sourceMap.SourcesContent = slice
}

// Attempt to fill in null entries using the file system
for i, source := range sourceMap.Sources {
if sourceMap.SourcesContent[i].Value == nil {
var absPath string
if args.fs.IsAbs(source) {
absPath = source
} else if path.Namespace == "file" {
absPath = args.fs.Join(args.fs.Dir(path.Text), source)
} else {
continue
}
if contents, err, _ := args.caches.FSCache.ReadFile(args.fs, absPath); err == nil {
sourceMap.SourcesContent[i].Value = helpers.StringToUTF16(contents)
}
}
sourceMap.SourcesContent = append(sourceMap.SourcesContent, sourceContent)
}
}

Expand Down
38 changes: 37 additions & 1 deletion scripts/verify-source-map.js
Expand Up @@ -402,6 +402,34 @@ const toSearchMissingSourcesContent = {
bar: 'src/foo.ts',
}

// The "null" should be filled in by the contents of "bar.ts"
const testCaseNullSourcesContent = {
'entry.js': `import './foo.js'\n`,
'foo.ts': `import './bar.ts'\nconsole.log("foo")`,
'bar.ts': `console.log("bar")\n`,
'foo.js': `(() => {
// bar.ts
console.log("bar");
// foo.ts
console.log("foo");
})();
//# sourceMappingURL=foo.js.map
`,
'foo.js.map': `{
"version": 3,
"sources": ["bar.ts", "foo.ts"],
"sourcesContent": [null, "import './bar.ts'\\nconsole.log(\\"foo\\")"],
"mappings": ";;AAAA,UAAQ,IAAI,KAAK;;;ACCjB,UAAQ,IAAI,KAAK;",
"names": []
}
`,
}

const toSearchNullSourcesContent = {
bar: 'bar.ts',
}

async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf, followUpFlags = [] }) {
let failed = 0

Expand Down Expand Up @@ -856,13 +884,21 @@ async function main() {
crlf,
}),

// Checks for loading missing sources content in nested source maps
// Checks for loading missing "sourcesContent" in nested source maps
check('missing-sources-content' + suffix, testCaseMissingSourcesContent, toSearchMissingSourcesContent, {
ext: 'js',
flags: flags.concat('--outfile=out.js', '--bundle'),
entryPoints: ['foo.js'],
crlf,
}),

// Checks for null entries in "sourcesContent" in nested source maps
check('null-sources-content' + suffix, testCaseNullSourcesContent, toSearchNullSourcesContent, {
ext: 'js',
flags: flags.concat('--outfile=out.js', '--bundle'),
entryPoints: ['foo.js'],
crlf,
}),
)
}
}
Expand Down

0 comments on commit e2993c0

Please sign in to comment.