From de0a310b821822642cefe5ba9d3cddc3575b001a Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Wed, 17 Aug 2022 14:32:25 -0700 Subject: [PATCH 1/3] Fix CSSStyleSheet is not defined error in node build --- .changeset/fifty-monkeys-shop.md | 6 ++++++ packages/lit-element/src/test/node-imports.ts | 19 ++++++++++++++++--- packages/reactive-element/src/css-tag.ts | 14 ++++++++++---- .../reactive-element/src/test/node-imports.ts | 19 ++++++++++++++++--- 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 .changeset/fifty-monkeys-shop.md diff --git a/.changeset/fifty-monkeys-shop.md b/.changeset/fifty-monkeys-shop.md new file mode 100644 index 0000000000..f45fb02760 --- /dev/null +++ b/.changeset/fifty-monkeys-shop.md @@ -0,0 +1,6 @@ +--- +'lit-element': patch +'lit': patch +--- + +Fix `CSSStyleSheet is not defined` error that would occur when importing a Lit component in Node when both static `styles` and the `@property` decorator were used. diff --git a/packages/lit-element/src/test/node-imports.ts b/packages/lit-element/src/test/node-imports.ts index 59f35e60a0..b9340f061c 100644 --- a/packages/lit-element/src/test/node-imports.ts +++ b/packages/lit-element/src/test/node-imports.ts @@ -21,13 +21,26 @@ import 'lit-element/decorators/query-assigned-elements.js'; import 'lit-element/decorators/query-assigned-nodes.js'; import 'lit-element/decorators/query-async.js'; -import {LitElement, html} from 'lit-element'; -import {customElement} from 'lit-element/decorators.js'; +import {LitElement, html, css} from 'lit-element'; +import {customElement, property} from 'lit-element/decorators.js'; @customElement('my-element') export class MyElement extends LitElement { + // Include both static styles and a @property decorator in the test. The + // @property decorator trigggers class initialization, and if there are also + // static styles, it will trigger a test for adopted stylesheets, which could + // explode if not handled with care in the node build. + static override styles = css` + p { + color: purple; + } + `; + + @property() + name = 'World'; + override render() { - return html`Hello World`; + return html`

Hello ${this.name}

`; } } diff --git a/packages/reactive-element/src/css-tag.ts b/packages/reactive-element/src/css-tag.ts index bbd00674a4..eb6e1a0334 100644 --- a/packages/reactive-element/src/css-tag.ts +++ b/packages/reactive-element/src/css-tag.ts @@ -11,10 +11,16 @@ const global = NODE_MODE ? globalThis : window; * Whether the current browser supports `adoptedStyleSheets`. */ export const supportsAdoptingStyleSheets = - global.ShadowRoot && - (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && - 'adoptedStyleSheets' in Document.prototype && - 'replace' in CSSStyleSheet.prototype; + // In Node mode, it doesn't really matter whether we believe adopted style + // sheets are supported or not, because styles are handled separately as part + // of SSR anyway; however if we set this to true then we avoid `instanceof + // CSSStyleSheet` checks during initialization, meaning we don't need to shim + // that global. + NODE_MODE || + (global.ShadowRoot && + (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && + 'adoptedStyleSheets' in Document.prototype && + 'replace' in CSSStyleSheet.prototype); /** * A CSSResult or native CSSStyleSheet. diff --git a/packages/reactive-element/src/test/node-imports.ts b/packages/reactive-element/src/test/node-imports.ts index 9d91df2af2..5d34c77f92 100644 --- a/packages/reactive-element/src/test/node-imports.ts +++ b/packages/reactive-element/src/test/node-imports.ts @@ -22,11 +22,24 @@ import '@lit/reactive-element/decorators/query-assigned-elements.js'; import '@lit/reactive-element/decorators/query-assigned-nodes.js'; import '@lit/reactive-element/decorators/query-async.js'; -import {customElement} from '@lit/reactive-element/decorators.js'; -import {ReactiveElement} from '@lit/reactive-element'; +import {customElement, property} from '@lit/reactive-element/decorators.js'; +import {ReactiveElement, css} from '@lit/reactive-element'; @customElement('my-element') -export class MyElement extends ReactiveElement {} +export class MyElement extends ReactiveElement { + // Include both static styles and a @property decorator in the test. The + // @property decorator trigggers class initialization, and if there are also + // static styles, it will trigger a test for adopted stylesheets, which could + // explode if not handled with care in the node build. + static override styles = css` + p { + color: purple; + } + `; + + @property() + name = 'World'; +} export class MyOtherElement extends ReactiveElement {} customElements.define('my-other-element', MyOtherElement); From 2a38f2baff548ab04bd3001c322c8309ccc347df Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Wed, 17 Aug 2022 17:06:57 -0700 Subject: [PATCH 2/3] Address review feedback --- .changeset/fifty-monkeys-shop.md | 2 +- packages/lit-element/src/test/node-imports.ts | 19 +++------------ packages/reactive-element/src/css-tag.ts | 24 ++++++++----------- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/.changeset/fifty-monkeys-shop.md b/.changeset/fifty-monkeys-shop.md index f45fb02760..fa0aa14203 100644 --- a/.changeset/fifty-monkeys-shop.md +++ b/.changeset/fifty-monkeys-shop.md @@ -1,5 +1,5 @@ --- -'lit-element': patch +'@lit/reactive-element': patch 'lit': patch --- diff --git a/packages/lit-element/src/test/node-imports.ts b/packages/lit-element/src/test/node-imports.ts index b9340f061c..59f35e60a0 100644 --- a/packages/lit-element/src/test/node-imports.ts +++ b/packages/lit-element/src/test/node-imports.ts @@ -21,26 +21,13 @@ import 'lit-element/decorators/query-assigned-elements.js'; import 'lit-element/decorators/query-assigned-nodes.js'; import 'lit-element/decorators/query-async.js'; -import {LitElement, html, css} from 'lit-element'; -import {customElement, property} from 'lit-element/decorators.js'; +import {LitElement, html} from 'lit-element'; +import {customElement} from 'lit-element/decorators.js'; @customElement('my-element') export class MyElement extends LitElement { - // Include both static styles and a @property decorator in the test. The - // @property decorator trigggers class initialization, and if there are also - // static styles, it will trigger a test for adopted stylesheets, which could - // explode if not handled with care in the node build. - static override styles = css` - p { - color: purple; - } - `; - - @property() - name = 'World'; - override render() { - return html`

Hello ${this.name}

`; + return html`Hello World`; } } diff --git a/packages/reactive-element/src/css-tag.ts b/packages/reactive-element/src/css-tag.ts index eb6e1a0334..640d66f59b 100644 --- a/packages/reactive-element/src/css-tag.ts +++ b/packages/reactive-element/src/css-tag.ts @@ -11,16 +11,10 @@ const global = NODE_MODE ? globalThis : window; * Whether the current browser supports `adoptedStyleSheets`. */ export const supportsAdoptingStyleSheets = - // In Node mode, it doesn't really matter whether we believe adopted style - // sheets are supported or not, because styles are handled separately as part - // of SSR anyway; however if we set this to true then we avoid `instanceof - // CSSStyleSheet` checks during initialization, meaning we don't need to shim - // that global. - NODE_MODE || - (global.ShadowRoot && - (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && - 'adoptedStyleSheets' in Document.prototype && - 'replace' in CSSStyleSheet.prototype); + global.ShadowRoot && + (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && + 'adoptedStyleSheets' in Document.prototype && + 'replace' in CSSStyleSheet.prototype; /** * A CSSResult or native CSSStyleSheet. @@ -201,7 +195,9 @@ const cssResultFromStyleSheet = (sheet: CSSStyleSheet) => { return unsafeCSS(cssText); }; -export const getCompatibleStyle = supportsAdoptingStyleSheets - ? (s: CSSResultOrNative) => s - : (s: CSSResultOrNative) => - s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s; +export const getCompatibleStyle = + supportsAdoptingStyleSheets || + (NODE_MODE && global.CSSStyleSheet === undefined) + ? (s: CSSResultOrNative) => s + : (s: CSSResultOrNative) => + s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s; From 75ac22f07d01dd7055b936eebb8546c5ac6527ec Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Wed, 17 Aug 2022 17:12:06 -0700 Subject: [PATCH 3/3] Clarify comment --- packages/reactive-element/src/test/node-imports.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/reactive-element/src/test/node-imports.ts b/packages/reactive-element/src/test/node-imports.ts index 5d34c77f92..39a58f7760 100644 --- a/packages/reactive-element/src/test/node-imports.ts +++ b/packages/reactive-element/src/test/node-imports.ts @@ -29,8 +29,8 @@ import {ReactiveElement, css} from '@lit/reactive-element'; export class MyElement extends ReactiveElement { // Include both static styles and a @property decorator in the test. The // @property decorator trigggers class initialization, and if there are also - // static styles, it will trigger a test for adopted stylesheets, which could - // explode if not handled with care in the node build. + // static styles, it will trigger an instanceof check for CSSStyleSheet, which + // could explode if not handled with care in the node build. static override styles = css` p { color: purple;