Skip to content
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

Consolidate viewer functionality into main report #1594

Merged
merged 13 commits into from
Feb 9, 2017

Conversation

ebidel
Copy link
Contributor

@ebidel ebidel commented Feb 1, 2017

R: all

This is the finale of #1169. But unlike that PR, this does not introduce a build step to lighthouse-core!

Now, all generated reports (cli/extension/viewer) have the full export button goodness:

screen shot 2017-01-31 at 5 53 51 pm

The share button is still specific to viewer:

screen shot 2017-01-31 at 5 54 13 pm

/**
* Handler copy events.
*/
onCopy(e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly moving code from viewer -> lighthouse-report.js

// If in Node, allow others to require us. By default, browser code can juse
// use the LighthouseReport class.
if (typeof module !== 'undefined') {
// Allow Node code to use require(). Browser code can use the LighthouseReport
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open to suggestions on this. There might be a Node-ier want to do this but I think it's simple enough.

Viewer still browserifies the code, so we keep requires for that and omit them for the browser context.

@@ -67,4 +67,6 @@ class Logger {
}
}

module.exports = new Logger('#log'); // singleton
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got rid of the nasty dom singleton. Viewer and the core report each defines their own logger now.

'use strict';

/**
* Note: getFilenamePrefix is duplicated from asset-saver.js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm up for suggestions on this too. We could factor out getFilenamePrefix from asset-saver.js and make it work in both Node and the browser.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this. Let's split into its own module or whatever?

Definitely shouldn't duplicate it here if we dont have to

@@ -26,11 +26,14 @@ const PAGE = fs.readFileSync(path.join(__dirname, '../app/index.html'), 'utf8');
function setupJsDomGlobals() {
global.document = jsdom.jsdom(PAGE);
global.window = global.document.defaultView;
global.logger = console;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stub

@ebidel
Copy link
Contributor Author

ebidel commented Feb 2, 2017

rebased

@ebidel
Copy link
Contributor Author

ebidel commented Feb 3, 2017

rebased

'use strict';

/**
* Note: getFilenamePrefix is duplicated from asset-saver.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this. Let's split into its own module or whatever?

Definitely shouldn't duplicate it here if we dont have to

assert.ok(html.includes('printButton = document.querySelector'),
'print button functionality attached');
assert.ok(html.includes('openButton = document.querySelector'),
'open button functionality attached');
assert.ok(html.includes('share js-share'), 'has share button');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess it'd be a pain to assert that the share icon has display:none in this case, yeah?

ah well.

@ebidel
Copy link
Contributor Author

ebidel commented Feb 6, 2017

PTAL. Moved out getFilenamePrefix into a separate file so it could be require'd or used directly in the browser.

@brendankenny
Copy link
Member

this might need a fix now that getFilenamePrefix is used in a few other places due to #1601, sorry :(

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this didn't get looked at sooner.

This is looking good, and I really like the simplification it's doing, but I still feel like I need a diagram for our three(?) different reports, which scripts are included in each, and how they're each included.

Part of the issue is probably LighthouseViewerReport extending LighthouseReport but also creating a LighthouseReport to display it, just not including any of the script parts of it. I wonder if there's more we can do to tease this apart in the future.

*/
function getFilenamePrefix(results) {
// eslint-disable-next-line no-undef
const hostname = new (URLConstructor || URL)(results.url).hostname;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url-shim already guards against this. Any way we could rely on that and avoid this (and the require() below)? Since file-namer isn't included via script tag it seems like it's doable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't see a way around it.

For node code, we need to require('url-shim') to get URL. But if you do this instead:

let URL;
if (typeof module !== 'undefined' && module.exports) {
  URL = require('./url-shim');
  ...
}

You'll end up with URL === undefined in the browser. filer-namer.js gets <script> included in the main report here: https://github.com/GoogleChrome/lighthouse/pull/1594/files#diff-6a4779f17aa030f3223e4de92085eda9R227

module.exports = {
"extends": "../../../.eslintrc.js",
"env": {
"browser": true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 good call

@brendankenny
Copy link
Member

Part of the issue is probably LighthouseViewerReport extending LighthouseReport but also creating a LighthouseReport to display it, just not including any of the script parts of it. I wonder if there's more we can do to tease this apart in the future.

Thinking about this more, I realize part of this setup is precisely because we're trying to avoid a build step in lighthouse-core :)

@ebidel
Copy link
Contributor Author

ebidel commented Feb 7, 2017

this might need a fix now that getFilenamePrefix is used in a few other places due to #1601

We should be covered. asset-saver.js imports require('file-namer.js').getFilenamePrefix and still exports it for backwards compatibility.

@@ -247,8 +249,14 @@ <h2 class="config-section__title">Blocked URL Patterns</h2>
{{/each}}

<script>
window.addEventListener('DOMContentLoaded', _ => {
new LighthouseReport(window.lhresults);
(function(exports) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about moving this into its own script (report-startup or whatever) and included in ReportGenerator.getReportJS if reportContext is cli or extension? That seems like it may be clearer it's just for that context, but I'm not sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, but does it buy anything?

Viewer has similar init code and uses a main.js. But the only reason I put that a separate script was because the code uses require().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was that it may make the execution flow clearer since report-template.html is used for the report and viewer but this script is only for report, not viewer.

Mostly I'm trying to look at my own confusion when I come back to this split and trying to think of ways to make it easier :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(come to think of it, none of the scripts injected by getReportJS are used by the viewer, right?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Nothing here ends up in Viewer. Because of that, we should avoid adding things to getReport* that are specific to the main report and never used elsewhere. This is a good example, where the init code is specific to the page. Otherwise the browserified bundle gets larger :\

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our own conservation of mass!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay on the one hand we have
image
but then here we have
image

so yeah im pretty confused as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay here's how report-generator is consumed:
image

viewer/app/src/main and lighthouse-background are browserified and used in the viewer and extension/devtools, respectively.

question:

  • why is report-generator including the source of scripts/lighthouse-report into the report when that file was already part of the bundle that shipped with the viewer

also, can we rename some of these files, because they all sound like the same thing right now. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the confusion mostly about the inline <script> at the bottom of report-template.html (@paulirish's 2nd screenshot)? I can create a separate .js file with the DOMContentLoaded setup and load it in the getReportJS() array. Would that help?

why is report-generator including the source of scripts/lighthouse-report into the report...

report-generator.js has always included the ligthhouse-report.js source into the report. I didn't change that setup. The only difference in this PR is that we're inlining more JS into the report (logger.js + filer-namer.js + lighthouse-report.js).

....when that file was already part of the bundle that shipped with the viewer

Viewer bundles report-generator.js as-is because it needs all the mechanics that generate the HTML report. Viewer needs all of report-generator.js because it dynamically generates an HTML report when the user drops a json file, pastes a link, or deep links from github. The idea was that we have the same codepath (ReportGenerator.generateHTML()) generating HTML for all three: crx/cli/viewer.

also, can we rename some of these files, because they all sound like the same thing right now. :)

Partially why I'm advocating we don't create more micro files :) lighthouse-report.js and the viewer's subclass (lighthouse-report-viewer.js) make sense to me, but I'm open to renaming.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, I'm not stoked on moving this:

window.addEventListener('DOMContentLoaded', _ => {
  window.logger = new Logger('#log');
  new LighthouseReport(window.lhresults);
});

into a separate script. There's little value in doing that. Plus, it'll need a license header and a bunch of eslint ignore boilerplate. All of that will add to our browserified bundles.

Next step is to kill some of that extra stuff in #1670

@brendankenny
Copy link
Member

We should be covered. asset-saver.js imports require('file-namer.js').getFilenamePrefix and still exports it for backwards compatibility.

Ah, I see. It seems like that should be dropped and the reference and tests moved from asset-saver-test to file-namer-test, though

@ebidel
Copy link
Contributor Author

ebidel commented Feb 7, 2017

Ah, I see. It seems like that should be dropped and the reference and tests moved from asset-saver-test to file-namer-test, though

Done. PTAL

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an improvement in every way over the current situation, so LGTM

(but I'll continue to lodge complaints that we need to keep simplifying this so I can actually understand what goes where without getting 11 comments into it :P)

</script>
{{/if}}
{{/if}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/* app z-indexes */
.log-wrapper {
z-index: 3;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -222,7 +222,11 @@ class ReportGenerator {
if (reportContext === 'devtools') {
return [];
} else {
return [fs.readFileSync(path.join(__dirname, './scripts/lighthouse-report.js'), 'utf8')];
return [
fs.readFileSync(path.join(__dirname, './scripts/logger.js'), 'utf8'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can drop the path.join and just fs.readFileSync(__dirname + '/scripts/logger.js'), 'utf8')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, just stuck with what we had in getReportCSS and getExceptionTemplate

@ebidel
Copy link
Contributor Author

ebidel commented Feb 8, 2017

Ready freddie.

@brendankenny brendankenny merged commit 9ac57cb into master Feb 9, 2017
@brendankenny brendankenny deleted the consolidatereport branch February 9, 2017 01:37
@ebidel
Copy link
Contributor Author

ebidel commented Feb 9, 2017

💥

@paulirish
Copy link
Member

paulirish commented Feb 9, 2017

🎐 🚶 🥇

(edit: before you try to hurt your brain on this.. i just picked emojis that sounded nice :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants