-
Notifications
You must be signed in to change notification settings - Fork 392
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
fix: implement stylesheet registration and disallow arbitrary functions #3443
Conversation
packages/@lwc/integration-karma/test/api/registerStylesheet/index.spec.js
Outdated
Show resolved
Hide resolved
@@ -275,3 +281,18 @@ export function createStylesheet(vm: VM, stylesheets: string[]): VNode[] | null | |||
} | |||
return null; | |||
} | |||
|
|||
const signedStylesheetSet: Set<StylesheetFactory> = new Set(); |
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 always found it odd that we used Maps/Sets for registering components/templates (rather than a WeakMap/WeakSet), but this is fine since today there is no way to GC these anyway.
In the future, if we ever add the ability to GC/evict components/templates/stylesheets, then we can change these to weak collections.
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.
Side note: it looks like we won't need to update the ACT compiler, because apparently it doesn't emit stylesheets. (At least, our tests in packages/@lwc/integration-karma/test/act/act-components
don't have any.) But it might be good to double-check.
This PR largely LGTM, although of course there is the risk of breakage. People really shouldn't be using arbitrary functions-that-return-strings, but of course they might be. The most prudent would be to make this a warning rather than an error, and roll it out with the reporting API first.
It depends on our appetite for risk, and how much breakage we think this will cause. WDYT?
I'll double check the ACT. I like the idea of making this a warning first and integrating it into the reporting API as a low-risk rollout. Risk of breakage is fairly low, but I think our appetite for risk is also medium low right now. I'd also like to get Alex's take on our org's overall appetite for risk, so in the meantime, we can use warning+reporting. |
Sounds good. At the very least, we can get early data from first-party components. I suspect those are the most likely to be exploiting loopholes in LWC like this anyway. |
@@ -47,6 +48,7 @@ export type ReportingPayloadMapping = { | |||
[ReportingEventId.NonStandardAriaReflection]: NonStandardAriaReflectionPayload; | |||
[ReportingEventId.TemplateMutation]: TemplateMutationPayload; | |||
[ReportingEventId.StylesheetMutation]: StylesheetMutationPayload; | |||
[ReportingEventId.UnexpectedStylesheetContent]: BasePayload; |
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 originally had a payload interface for this, but I don't see a point since we don't need any properties beyond what's provided by BasePayload
. We can always add a new payload interface if that ever changes.
`TypeError: Unexpected LWC stylesheet content found for component <${vm.tagName.toLowerCase()}>.` | ||
); | ||
report(ReportingEventId.UnexpectedStylesheetContent, { | ||
tagName: vm.tagName.toLowerCase(), |
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.
Is there ever any functional difference between vm.elm.tagName
and vm.tagName
? I noticed we use the former for non-standard-aria and the latter for cross-root-aria and static stylesheet validation
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 don't think there's a difference, no. I was probably just being inconsistent. 😅
Checked the ACT and as far as I could see we don't emit any stylesheets there. I couldn't find any references to stylesheets except for a single |
logError( | ||
`TypeError: Unexpected LWC stylesheet content found for component <${vm.tagName.toLowerCase()}>.` | ||
); |
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 error should only be logged in dev mode, and should also only be logged once ideally. I'd use the existing logWarnOnce
, or create a new one called logErrorOnce
. (In practice, it doesn't matter much whether the text is yellow or red IMO. 😄)
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.
Went with logWarnOnce
. This should now be consistent with how we're reporting and logging the other deprecated features.
report(ReportingEventId.UnexpectedStylesheetContent, { | ||
tagName: vm.tagName.toLowerCase(), | ||
}); | ||
continue; |
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 continue
makes this a functional (breaking) change. My understanding was that we were just going to warn, but still call the stylesheet function?
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.
Also, let's log a GH issue to track converting the warning into an error, then mention it with a TODO
comment here. We can add it to the breaking changes wishlist: #2964
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.
My bad, that detail slipped my mind. 👍 on logging a GH issue to convert the warning to error.
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.
To play it safe, can we also add a test to check that the CSS string returned by the arbitrary function is actually inserted into the DOM (e.g. with getComputedStyle
)? That would have caught the continue
.
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.
Just a few nitpicks, otherwise everything LGTM.
TODO: #3447 |
@@ -62,7 +62,7 @@ function checkAndReportViolation(elm: Element, prop: string, isSetter: boolean, | |||
if (process.env.NODE_ENV !== 'production') { | |||
logWarnOnce( | |||
`Element <${elm.tagName.toLowerCase()}> ` + | |||
(isUndefined(vm) ? '' : `owned by <${vm.elm.tagName.toLowerCase()}> `) + | |||
(isUndefined(vm) ? '' : `owned by <${vm.tagName.toLowerCase()}> `) + |
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.
Updated this to be consistent with everywhere else since this is the only place we do vm.elm.tagName
.
|
||
// TODO [#3447]: This test verifies existing behavior is maintained and should be removed | ||
// once the warnings are converted into errors. | ||
it('applies the styles if the arbitrary function returns a valid string', () => { |
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 test to verify existing behavior.
…ns (#3443) * fix: implement stylesheet registration and disallow arbitrary functions * feat: log as error and use reporting API * fix: move to dev-only warning, address PR comments * fix: add test to verify existing behavior is maintained * fix: only import registerStylesheet if new styles were compiled
Details
Implements registerStylesheet for marking stylesheets generated by the LWC compiler.
Restricts stylesheet evaluation to only those stylesheets.
Throws an error if arbitrary functions are found in the stylesheet list.
Addresses #3122 and #3156
Does this pull request introduce a breaking change?
This has the potential to break use cases relying on behaviors from arbitrary functions being executed as a stylesheet function:
<style>
tags,adoptedStylesheets
, etc).registerStylesheet
to components per [HMR] CSS: Provide a mechanism to register stylesheets #1887.Does this pull request introduce an observable change?
GUS work item
W-12040411