-
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: extract independent report types #12946
Conversation
@@ -0,0 +1,18 @@ | |||
/** |
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.
added a new eslintrc
for report/
to make it env
browser
and remove the ad hoc /* global document window */
and /* eslint-env browser */
s sprinkled throughout some of the files.
Also, turns out eslintrc files automatically extend any other eslintrc files up through to the root directory, though I added a root: true
in the root file just to make it clear
report/tsconfig.json
Outdated
// Limit to base JS and DOM defs. | ||
"lib": ["es2020", "dom", "dom.iterable"], | ||
// Include `@types/node` for use of `Buffer` in text-encoding.js. | ||
"types": ["node"], |
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.
the use of Buffer
in text-encoding.js
prevents getting rid of node
types for these files. I was tempted to write a little type shim just for Buffer
to keep out @types/node
, but it seemed a bit too fragile. Maybe worth it at some point
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.
the use of
Buffer
intext-encoding.js
prevents getting rid ofnode
types for these files. I was tempted to write a little type shim just forBuffer
to keep out@types/node
, but it seemed a bit too fragile. Maybe worth it at some point
trying out viewer types on top of this, I think we actually do want a little Buffer
shim. The node types infect everything (we end up with errors on setTimeout
return types, for instance, if viewer
doesn't also import @types/node
, which is just getting silly by that point)
{"path": "./generator/"} | ||
], | ||
"exclude": [ | ||
"generator/**/*.js", |
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.
I didn't realize generator/*
files would be included even though generator/
is in references
and has its own tsconfig
. Having to explicitly exclude these is one more argument not to nest generator
under report
, I think (see other options in #12940 (comment)).
@@ -45,5 +48,3 @@ declare global { | |||
signal?: AbortSignal; | |||
} | |||
} | |||
|
|||
export {}; |
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.
what's the force module situation these days such that this isn't necessary? I feel like I remember reading a PR description or comment about this recently, but couldn't find it quickly.
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.
what's the force module situation these days such that this isn't necessary? I feel like I remember reading a PR description or comment about this recently, but couldn't find it quickly.
it's kind of dumb: if there's any import
or export
statements, the file is a module (which is why we had the empty ones in there before when everything was in one or two files and we didn't have any imports), and if you want an explicit declare global {}
block in there it has to be a module, otherwise it's ambient and everything is a global type.
Fortunately(?) we almost always have import
statements these days, and the error message is a lot better, basically saying you can't declare global
unless this file is a module.
I vaguely recall a few years back in the es modules transition wars the idea of using that same heuristic to automatically detect if a file was an .mjs
vs .cjs
file without a file extension/package.json type
entry, and then everyone realized that would be super fragile and annoying and decided not to go that way. But here it is anyways :)
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.
LGTM
|
||
// Expose global types in LH namespace. | ||
module LH { | ||
export import ReportResult = _ReportResult; |
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.
Oh interesting I wouldn't have expected export import
to be needed since we're reassigning.
does this differ from export type ReportResult = _ReportResult;
or because it's a module we can't do that and export import
is the only valid way?
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.
Oh interesting I wouldn't have expected
export import
to be needed since we're reassigning.does this differ from
export type ReportResult = _ReportResult;
or because it's a module we can't do that andexport import
is the only valid way?
yeah, you get the interface but not the module, so e.g. LH.ReportResult.AuditRef
won't resolve
@@ -35,7 +35,7 @@ const URL_PREFIXES = ['http://', 'https://', 'data:']; | |||
export class DetailsRenderer { | |||
/** | |||
* @param {DOM} dom | |||
* @param {{fullPageScreenshot?: LH.Artifacts.FullPageScreenshot}} [options] | |||
* @param {{fullPageScreenshot?: LH.Audit.Details.FullPageScreenshot}} [options] |
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.
I think this starts to illustrate how the boundaries are hard to see here (glancing at this without context, I wouldn't expect LH.Audit
to be within the self-contained report context
Long-term do you plan to renamespace the report to LHReport
or LH.Report.
or similar?
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.
I think this starts to illustrate how the boundaries are hard to see here (glancing at this without context, I wouldn't expect
LH.Audit
to be within the self-contained report contextLong-term do you plan to renamespace the report to
LHReport
orLH.Report.
or similar?
Yeah, it's a really good question. I'm not sure. I defaulted to maintaining the familiar LH.*
hierarchy, but in the report files, the LH.Audit
namespace is empty except for Details
:
module LH {
module Audit {
export import Details = AuditDetails;
}
}
so seems doubly weird to maintain it? Not that useful in the report if considered in isolation, and if the goal is consistency across files, it's actually misleading because you might think e.g. LH.Audit.ScoreDisplayMode
is going to be in there too.
So long term it may make sense to re work the names, but then it's asking everyone to keep track of multiple names for the same thing...
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.
Maybe if microsoft/TypeScript#41825 is fixed, core could keep the global types and the other areas with fewer files and fewer type needs could just do
/** @typedef {import('../../lhr/audit-details')} AuditDetails */
export class DetailsRenderer {
/**
* @param {DOM} dom
* @param {{fullPageScreenshot?: AuditDetails.FullPageScreenshot}} [options]
*/
constructor(dom, options = {}) {
this._dom = dom;
this._fullPageScreenshot = options.fullPageScreenshot;
}
}
Without that issue fixed, though, we'd be stuck with
/** @typedef {import('../../lhr/audit-details').FullPageScreenshot} FullPageScreenshot */
/** @typedef {import('../../lhr/audit-details').OpportunityColumnHeading} OpportunityColumnHeading */
/** @typedef {import('../../lhr/audit-details').TableColumnHeading} TableColumnHeading */
/** @typedef {import('../../lhr/audit-details').List} List */
/** @typedef {import('../../lhr/audit-details').NodeValue} NodeValue */
// ...
:(
5533b93
to
789560b
Compare
Isolates
report/
as a typescript "project" allowing it to live off in its own type world. This allows it to be browser specific and not bring in the entire lighthouse-cli/lighthouse-core/etc world just to type check the report.Dependencies are simpler and (because of the expanded
-b
mode) more compilation caching occurs which means faster follow-up type checks (e.g. if you're working on core and haven't touched the report, theyarn tsc -b report/
part will finish in 200ms because the cached.tmp/tsbuildinfo
file will be newer than all the files inreport/
).The bulk of this PR is splitting up a few more
d.ts
files for e.g. the parts ofhtml-renderer.d.ts
thattreemap
andviewer
need vs the parts they don't.I'll follow this PR with changes to make
treemap/
,viewer/
, andflow-report/
to do the same to them. This will be especially helpful for treemap and viewer since they recompile large parts of core due to transitive type deps. There will also probably need to be a final clean up pass to better use tsconfig inheritance and some documentation.