-
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
core: adjustments to stack-pack comments and types #8169
Changes from all commits
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 |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
|
||
const log = require('lighthouse-logger'); | ||
const manifestParser = require('../lib/manifest-parser.js'); | ||
const stacksGatherer = require('../lib/gatherer-stacks.js'); | ||
const stacksGatherer = require('../lib/stack-collector.js'); | ||
const LHError = require('../lib/lh-error.js'); | ||
const URL = require('../lib/url-shim.js'); | ||
const NetworkRecorder = require('../lib/network-recorder.js'); | ||
|
@@ -412,7 +412,7 @@ class GatherRunner { | |
NetworkUserAgent: '', // updated later | ||
BenchmarkIndex: 0, // updated later | ||
WebAppManifest: null, // updated later | ||
Stacks: null, // updated later | ||
Stacks: [], // updated later | ||
traces: {}, | ||
devtoolsLogs: {}, | ||
settings: options.settings, | ||
|
@@ -480,12 +480,18 @@ class GatherRunner { | |
} | ||
await GatherRunner.beforePass(passContext, gathererResults); | ||
await GatherRunner.pass(passContext, gathererResults); | ||
|
||
if (isFirstPass) { | ||
// Fetch the manifest, if it exists. Currently must be fetched before gatherers' `afterPass`. | ||
baseArtifacts.WebAppManifest = await GatherRunner.getWebAppManifest(passContext); | ||
baseArtifacts.Stacks = await stacksGatherer(passContext); | ||
} | ||
|
||
const passData = await GatherRunner.afterPass(passContext, gathererResults); | ||
|
||
if (isFirstPass) { | ||
baseArtifacts.Stacks = await stacksGatherer(passContext); | ||
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. any reason for moving this after after pass? 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.
so we aren't tracing while it runs. The web manifest one can move out of during the trace too, but it has to be run before gatherer's 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. oh right, maybe add a comment to this effect? it's hard to remember all the steps that happen inside those when glancing at this section :) |
||
} | ||
|
||
// Save devtoolsLog, but networkRecords are discarded and not added onto artifacts. | ||
baseArtifacts.devtoolsLogs[passConfig.passName] = passData.devtoolsLog; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,45 +15,52 @@ | |
|
||
const fs = require('fs'); | ||
const libDetectorSource = fs.readFileSync( | ||
require.resolve('js-library-detector/library/libraries.js'), | ||
'utf8' | ||
); | ||
require.resolve('js-library-detector/library/libraries.js'), 'utf8'); | ||
|
||
/** @typedef {false | {version: string|null}} JSLibraryDetectorTestResult */ | ||
/** | ||
* @typedef JSLibraryDetectorTest | ||
* @property {string} icon Essentially an id, useful if no npm name is detected. | ||
* @property {string} url | ||
* @property {string|null} npm npm module name, if applicable to library. | ||
* @property {function(Window): JSLibraryDetectorTestResult | Promise<JSLibraryDetectorTestResult>} test Returns false if library is not present, otherwise returns an object that contains the library version (set to null if the version is not detected). | ||
*/ | ||
|
||
/** | ||
* @typedef JSLibrary | ||
* @property {string} name | ||
* @property {string} version | ||
* @property {string} npm | ||
* @property {string} iconName | ||
* @property {string} icon | ||
* @property {string|null} version | ||
* @property {string|null} npm | ||
*/ | ||
|
||
/** | ||
* Obtains a list of detected JS libraries and their versions. | ||
*/ | ||
/* istanbul ignore next */ | ||
function detectLibraries() { | ||
async function detectLibraries() { | ||
/** @type {JSLibrary[]} */ | ||
const libraries = []; | ||
|
||
// d41d8cd98f00b204e9800998ecf8427e_ is a consistent prefix used by the detect libraries | ||
// see https://github.com/HTTPArchive/httparchive/issues/77#issuecomment-291320900 | ||
/** @type {Record<string, JSLibraryDetectorTest>} */ | ||
// @ts-ignore - injected libDetectorSource var | ||
Object.entries(d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests).forEach( | ||
async ([name, lib]) => { | ||
// eslint-disable-line max-len | ||
try { | ||
const result = await lib.test(window); | ||
if (result) { | ||
libraries.push({ | ||
name: name, | ||
version: result.version, | ||
npm: lib.npm, | ||
iconName: lib.icon, | ||
}); | ||
} | ||
} catch (e) {} | ||
} | ||
); | ||
const libraryDetectorTests = d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests; // eslint-disable-line | ||
|
||
for (const [name, lib] of Object.entries(libraryDetectorTests)) { | ||
try { | ||
const result = await lib.test(window); | ||
if (result) { | ||
libraries.push({ | ||
name: name, | ||
icon: lib.icon, | ||
version: result.version, | ||
npm: lib.npm, | ||
}); | ||
} | ||
} catch (e) {} | ||
} | ||
|
||
return libraries; | ||
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. does this mean we always returned an empty array before? seems important enough to warrant a smoketest and separate fix if so 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.
when it was `JSLibraries? Yes.
an artifact smoketest would be excellent (we have an audit smoke test with the 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. I'm confused given your two answers as they seem mutually exclusive :) Given that we're not Yet our smoketest for this was still passing and you believe there's no fix necessary, so it seems like it wasn't always returning an empty array. I guess the answer is that because our evaluateAsync Promise wrapping logic in driver waits for all microtasks to complete, it's sort of coincidence that we were still getting all of the synchronously computed ones by Crazy times 😆 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. ohhh, I understand what you were asking. I thought you meant in the case where there were no libraries detected did we always return an array, even if empty :) Yes, it was buggy but accidentally working except for the |
||
} | ||
|
@@ -62,23 +69,22 @@ function detectLibraries() { | |
* @param {LH.Gatherer.PassContext} passContext | ||
* @return {Promise<LH.Artifacts['Stacks']>} | ||
*/ | ||
async function getStacks(passContext) { | ||
async function collectStacks(passContext) { | ||
const expression = `(function () { | ||
${libDetectorSource}; | ||
return (${detectLibraries.toString()}()); | ||
})()`; | ||
|
||
const jsLibraries = /** @type {JSLibrary[]} */ (await passContext.driver.evaluateAsync( | ||
expression | ||
)); | ||
/** @type {JSLibrary[]} */ | ||
const jsLibraries = await passContext.driver.evaluateAsync(expression); | ||
|
||
return jsLibraries.map(lib => ({ | ||
detector: /** @type {'js'} */ ('js'), | ||
id: lib.npm || lib.iconName, | ||
id: lib.npm || lib.icon, | ||
name: lib.name, | ||
version: lib.version, | ||
npm: lib.npm, | ||
version: lib.version || undefined, | ||
npm: lib.npm || undefined, | ||
})); | ||
} | ||
|
||
module.exports = getStacks; | ||
module.exports = collectStacks; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,42 +6,48 @@ | |
'use strict'; | ||
|
||
const stackPacks = require('@lighthouse/stack-packs'); | ||
const log = require('lighthouse-logger'); | ||
|
||
/** | ||
* Pairs consisting of a stack pack's ID and the set of stacks needed to be | ||
* detected in a page to display that pack's advice. | ||
* @type {Array<{packId: string, requiredStacks: Array<string>}>} | ||
*/ | ||
const stackPacksToInclude = [{ | ||
packId: 'wordpress', | ||
requiredStacks: ['js:wordpress'], | ||
}]; | ||
|
||
/** | ||
* @param {LH.Artifacts} artifacts | ||
* Returns all packs that match the stacks found in the page. | ||
* @param {LH.Artifacts['Stacks']} pageStacks | ||
* @return {Array<LH.Result.StackPack>} | ||
*/ | ||
function getStackPacks(artifacts) { | ||
function getStackPacks(pageStacks) { | ||
/** @type {Array<LH.Result.StackPack>} */ | ||
const packs = []; | ||
|
||
if (artifacts.Stacks) { | ||
for (const pageStack of artifacts.Stacks) { | ||
const stackPackToIncl = stackPacksToInclude.find(stackPackToIncl => | ||
stackPackToIncl.requiredStacks.includes(`${pageStack.detector}:${pageStack.id}`)); | ||
if (!stackPackToIncl) { | ||
continue; | ||
} | ||
|
||
// Grab the full pack definition | ||
const matchedPack = stackPacks.find(pack => pack.id === stackPackToIncl.packId); | ||
if (!matchedPack) { | ||
// we couldn't find a pack that's in our inclusion list, this is weird. | ||
continue; | ||
} | ||
|
||
packs.push({ | ||
id: matchedPack.id, | ||
title: matchedPack.title, | ||
iconDataURL: matchedPack.iconDataURL, | ||
descriptions: matchedPack.descriptions, | ||
}); | ||
for (const pageStack of pageStacks) { | ||
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. this is all just whitespace changes due to removing the |
||
const stackPackToIncl = stackPacksToInclude.find(stackPackToIncl => | ||
stackPackToIncl.requiredStacks.includes(`${pageStack.detector}:${pageStack.id}`)); | ||
if (!stackPackToIncl) { | ||
continue; | ||
} | ||
|
||
// Grab the full pack definition | ||
const matchedPack = stackPacks.find(pack => pack.id === stackPackToIncl.packId); | ||
if (!matchedPack) { | ||
log.warn('StackPacks', | ||
`'${stackPackToIncl.packId}' stack pack was matched but is not found in stack-packs lib`); | ||
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. except for warning here :) |
||
continue; | ||
} | ||
|
||
packs.push({ | ||
id: matchedPack.id, | ||
title: matchedPack.title, | ||
iconDataURL: matchedPack.iconDataURL, | ||
descriptions: matchedPack.descriptions, | ||
}); | ||
} | ||
|
||
return packs; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ | |
"URL": { | ||
"requestedUrl": "https://example.com/", | ||
"finalUrl": "https://example.com/" | ||
} | ||
}, | ||
"Stacks": [] | ||
} |
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.
this change was needed for supporting
for await...of
in our client minifying pipeline. It feels like we shouldn't need the plugin now that it's stage 4 and shipping everywhere, but I don't care enough to look into babel more :)note that this isn't transpiling anything (we only minify), it's just so the babel parser understands the syntax and doesn't throw when seeing this.
(no idea if the
brfs
change is needed, it's just that 10 is the latest version, so might as well)