Skip to content

Commit

Permalink
Use WHATWG's URL to implement all of source-map's URL operations. (#371)
Browse files Browse the repository at this point in the history
* Use WHATWG's URL to implement all of source-map's URL operations.

* Preserve string-concat sources behavior for absolute-path sources.

* Only use whatwg-url in browser builds.

* Optimize perf to avoid new URL where not strictly needed.

* Cache url -> source index lookups in the consumer.

* Simplify url cache size limiting.
  • Loading branch information
loganfsmyth authored Nov 15, 2018
1 parent 23104f3 commit 02f3d6b
Show file tree
Hide file tree
Showing 7 changed files with 387 additions and 427 deletions.
18 changes: 16 additions & 2 deletions lib/source-map-consumer.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ class BasicSourceMapConsumer extends SourceMapConsumer {
throw new Error("Unsupported version: " + version);
}

that._sourceLookupCache = new Map();

// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
Expand Down Expand Up @@ -227,18 +229,30 @@ class BasicSourceMapConsumer extends SourceMapConsumer {
* found.
*/
_findSourceIndex(aSource) {
// In the most common usecases, we'll be constantly looking up the index for the same source
// files, so we cache the index lookup to avoid constantly recomputing the full URLs.
const cachedIndex = this._sourceLookupCache.get(aSource);
if (typeof cachedIndex === "number") {
return cachedIndex;
}

// Treat the source as map-relative overall by default.
const sourceAsMapRelative = util.computeSourceURL(null, aSource, this._sourceMapURL);
if (this._absoluteSources.has(sourceAsMapRelative)) {
return this._absoluteSources.indexOf(sourceAsMapRelative);
const index = this._absoluteSources.indexOf(sourceAsMapRelative);
this._sourceLookupCache.set(aSource, index);
return index;
}

// Fall back to treating the source as sourceRoot-relative.
const sourceAsSourceRootRelative = util.computeSourceURL(this.sourceRoot, aSource, this._sourceMapURL);
if (this._absoluteSources.has(sourceAsSourceRootRelative)) {
return this._absoluteSources.indexOf(sourceAsSourceRootRelative);
const index = this._absoluteSources.indexOf(sourceAsSourceRootRelative);
this._sourceLookupCache.set(aSource, index);
return index;
}

// To avoid this cache growing forever, we do not cache lookup misses.
return -1;
}

Expand Down
21 changes: 21 additions & 0 deletions lib/url-browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
"use strict";

/**
* Browser 'URL' implementations have been found to handle non-standard URL
* schemes poorly, and schemes like
*
* webpack:///src/folder/file.js
*
* are very common in source maps. For the time being we use a JS
* implementation in these contexts instead. See
*
* * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505
* * https://bugs.chromium.org/p/chromium/issues/detail?id=734880
*/
module.exports = require("whatwg-url").URL;
13 changes: 13 additions & 0 deletions lib/url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
"use strict";

// Note: This file is overridden in the 'package.json#browser' field to
// substitute lib/url-browser.js instead.

// Use the URL global for Node 10, and the 'url' module for Node 8.
module.exports = typeof URL === "function" ? URL : require("url").URL;
Loading

0 comments on commit 02f3d6b

Please sign in to comment.