-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
report: use source maps to show original file name #10930
Changes from 9 commits
25493dd
15009ae
cfd62ed
d61abda
f22bd04
5cd23f8
832ceca
7af5053
9ceca12
3feb713
16b7771
c63b65e
0fbf2fc
e853c83
49d19be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -144,7 +144,7 @@ class DetailsRenderer { | |||||||
|
||||||||
/** | ||||||||
* @param {{text: string, url: string}} details | ||||||||
* @return {Element} | ||||||||
* @return {HTMLElement} | ||||||||
*/ | ||||||||
_renderLink(details) { | ||||||||
const allowedProtocols = ['https:', 'http:']; | ||||||||
|
@@ -551,22 +551,39 @@ class DetailsRenderer { | |||||||
} | ||||||||
|
||||||||
// Lines are shown as one-indexed. | ||||||||
const line = item.line + 1; | ||||||||
const column = item.column; | ||||||||
const generatedLocation = `${item.url}:${item.line + 1}:${item.column}`; | ||||||||
let originalLocation; | ||||||||
if (item.original) { | ||||||||
const file = item.original.file || '<unmapped>'; | ||||||||
originalLocation = `${file}:${item.original.line + 1}:${item.original.column}`; | ||||||||
} | ||||||||
|
||||||||
// We render slightly differently based on presence of source map and provenance of URL. | ||||||||
let element; | ||||||||
if (item.urlProvider === 'network') { | ||||||||
if (item.urlProvider === 'network' && originalLocation) { | ||||||||
element = this._renderLink({ | ||||||||
url: item.url, | ||||||||
text: originalLocation, | ||||||||
}); | ||||||||
element.title = `maps to generated location ${generatedLocation}`; | ||||||||
} else if (item.urlProvider === 'network' && !originalLocation) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
element = this.renderTextURL(item.url); | ||||||||
this._dom.find('.lh-link', element).textContent += `:${line}:${column}`; | ||||||||
this._dom.find('.lh-link', element).textContent += `:${item.line + 1}:${item.column}`; | ||||||||
} else if (item.urlProvider === 'comment' && originalLocation) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
element = this._renderText(`${originalLocation} (from source map)`); | ||||||||
element.title = `${generatedLocation} (from sourceURL)`; | ||||||||
} else if (item.urlProvider === 'comment' && !originalLocation) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
element = this._renderText(`${generatedLocation} (from sourceURL)`); | ||||||||
} else { | ||||||||
element = this._renderText(`${item.url}:${line}:${column} (from sourceURL)`); | ||||||||
return null; | ||||||||
} | ||||||||
|
||||||||
element.classList.add('lh-source-location'); | ||||||||
element.setAttribute('data-source-url', item.url); | ||||||||
// DevTools expects zero-indexed lines. | ||||||||
element.setAttribute('data-source-line', String(item.line)); | ||||||||
element.setAttribute('data-source-column', String(item.column)); | ||||||||
|
||||||||
return element; | ||||||||
} | ||||||||
|
||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -492,6 +492,37 @@ describe('DetailsRenderer', () => { | |
assert.equal(sourceLocationEl.getAttribute('data-source-column'), `${sourceLocation.column}`); | ||
}); | ||
|
||
it('renders source-location values using source map data', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. may need a few more tests to hit the different cases, e.g. when there's no source map and the |
||
const sourceLocation = { | ||
type: 'source-location', | ||
url: 'https://www.example.com/script.js', | ||
urlProvider: 'network', | ||
line: 10, | ||
column: 5, | ||
original: { | ||
file: 'main.js', | ||
line: 100, | ||
column: 10, | ||
}, | ||
}; | ||
const details = { | ||
type: 'table', | ||
headings: [{key: 'content', itemType: 'source-location', text: 'Heading'}], | ||
items: [{content: sourceLocation}], | ||
}; | ||
|
||
const el = renderer.render(details); | ||
const sourceLocationEl = el.querySelector('.lh-source-location.lh-link'); | ||
assert.strictEqual(sourceLocationEl.localName, 'a'); | ||
assert.equal(sourceLocationEl.href, 'https://www.example.com/script.js'); | ||
assert.equal(sourceLocationEl.textContent, 'main.js:101:10'); | ||
assert.equal(sourceLocationEl.title, 'maps to generated location https://www.example.com/script.js:11:5'); | ||
// DevTools should still use the generated location. | ||
assert.equal(sourceLocationEl.getAttribute('data-source-url'), sourceLocation.url); | ||
assert.equal(sourceLocationEl.getAttribute('data-source-line'), `${sourceLocation.line}`); | ||
assert.equal(sourceLocationEl.getAttribute('data-source-column'), `${sourceLocation.column}`); | ||
}); | ||
|
||
it('renders source-location with lh-link class for relative url', () => { | ||
const sourceLocation = { | ||
type: 'source-location', | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -218,12 +218,23 @@ declare global { | |||||
*/ | ||||||
export interface SourceLocationValue { | ||||||
type: 'source-location'; | ||||||
/** urls from the network are always valid urls. otherwise, urls come from either a comment or header, and may not be well-formed. */ | ||||||
/** urls from the network are always valid urls. otherwise, urls come from either a comment or header (see urlProvider), and may not be well-formed. */ | ||||||
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
url: string; | ||||||
/** 'network' when the url is the actual, observed resource url. 'comment' when the url comes from a sourceMapURL comment or X-SourceMap header */ | ||||||
/** | ||||||
* - `network` when the url is the actual, observed resource url. | ||||||
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
* - `comment` when the url comes from a sourceMapURL comment or X-SourceMap header | ||||||
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
*/ | ||||||
urlProvider: 'network' | 'comment'; | ||||||
/** Zero-indexed. */ | ||||||
line: number; | ||||||
column: number; | ||||||
/** The original file location from the source map. */ | ||||||
original?: { | ||||||
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
/** The relevant file from the map's `sources` array. If missing, could not associate mapping with a specific file ("unmapped" in other tools). */ | ||||||
file?: string; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a useless state? Are the line/col numbers still useful if we can't say which file the line/col numbers are in? |
||||||
line: number; | ||||||
column: number; | ||||||
}; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also... do you know what's up with this comment? lighthouse/types/audit-details.d.ts Line 221 in 40baa22
" urls from the network are always valid urls" vs "urls [...] may not be well-formed" 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can put absolutely anything in a soruceMappingURL comment or the associated header. Treating this user input as a well-formed URL is error prone. In some cases the protocol hides the true resource (network) url from us, if there is a comment url present. see
so we must have a distinction between these two sources of "url", which is what |
||||||
} | ||||||
|
||||||
/** | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mind if we add some comments in here? i always forget what urlProvider is about and wouldn't mind having a lil cheatsheet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this why we write jsdocs? hovering over this field in vs code will show this info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
originalLocation
is aliased tohasSourceMap
, plus we consider what I said above, it seems the code would be saying the same as your suggested comments. wdyt?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah adding a
hasSourceMap
var seems nice. That plus the upgraded .d.ts comments sorts this out completely.