From e5c254e96cb5d0f770ec616332e231559325c5c5 Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Wed, 11 Jan 2023 17:22:05 -0800 Subject: [PATCH] [reactive-element] Fix Node build auto-shimming of `HTMLElement` to respect existing global shim (#3561) * Update rollup plugin-replace * Add changesets * Add tests for dom shim * Update .changeset/tidy-lamps-rest.md Co-authored-by: Alexander Marks Co-authored-by: Alexander Marks --- .changeset/thick-wasps-love.md | 6 + .changeset/tidy-lamps-rest.md | 6 + package-lock.json | 108 +++++++++++++++--- package.json | 2 +- packages/lit-starter-js/package.json | 2 +- packages/lit-starter-ts/package.json | 2 +- packages/reactive-element/package.json | 24 +++- .../src/test/node-dom-shim.ts | 25 ++++ .../reactive-element/src/test/node-imports.ts | 8 ++ .../src/test/node-shim-html-element.ts | 11 ++ rollup-common.js | 1 + 11 files changed, 175 insertions(+), 20 deletions(-) create mode 100644 .changeset/thick-wasps-love.md create mode 100644 .changeset/tidy-lamps-rest.md create mode 100644 packages/reactive-element/src/test/node-dom-shim.ts create mode 100644 packages/reactive-element/src/test/node-shim-html-element.ts diff --git a/.changeset/thick-wasps-love.md b/.changeset/thick-wasps-love.md new file mode 100644 index 0000000000..d09291f9f7 --- /dev/null +++ b/.changeset/thick-wasps-love.md @@ -0,0 +1,6 @@ +--- +'@lit/lit-starter-js': patch +'@lit/lit-starter-ts': patch +--- + +Update dependency `@rollup/plugin-replace` diff --git a/.changeset/tidy-lamps-rest.md b/.changeset/tidy-lamps-rest.md new file mode 100644 index 0000000000..c8ffe0a537 --- /dev/null +++ b/.changeset/tidy-lamps-rest.md @@ -0,0 +1,6 @@ +--- +'lit': patch +'@lit/reactive-element': patch +--- + +Fix built-in shimming of `HTMLElement` for Node build of `reactive-element` to respect existing `HTMLElement` in global diff --git a/package-lock.json b/package-lock.json index dfee001dd9..0d128bf747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-inject": "^5.0.2", "@rollup/plugin-node-resolve": "^13.2.1", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@rollup/plugin-virtual": "^2.1.0", "@types/chai": "^4.3.1", "@types/mocha": "^9.1.1", @@ -3525,16 +3525,64 @@ } }, "node_modules/@rollup/plugin-replace": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-4.0.0.tgz", - "integrity": "sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", + "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, + "node_modules/@rollup/plugin-replace/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" } }, "node_modules/@rollup/plugin-typescript": { @@ -24485,7 +24533,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@web/dev-server": "^0.1.31", "@web/dev-server-legacy": "^1.0.0", "@web/test-runner": "^0.13.27", @@ -24513,7 +24561,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@typescript-eslint/eslint-plugin": "^5.25.0", "@typescript-eslint/parser": "^5.25.0", "@web/dev-server": "^0.1.31", @@ -26914,7 +26962,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "5.0.2", "@web/dev-server": "^0.1.31", "@web/dev-server-legacy": "^1.0.0", "@web/test-runner": "^0.13.27", @@ -26938,7 +26986,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "5.0.2", "@typescript-eslint/eslint-plugin": "^5.25.0", "@typescript-eslint/parser": "^5.25.0", "@web/dev-server": "^0.1.31", @@ -27783,13 +27831,41 @@ } }, "@rollup/plugin-replace": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-4.0.0.tgz", - "integrity": "sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", + "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.27.0" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, + "magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + } } }, "@rollup/plugin-typescript": { diff --git a/package.json b/package.json index 76cebc221d..1507cb82ac 100644 --- a/package.json +++ b/package.json @@ -185,7 +185,7 @@ "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-inject": "^5.0.2", "@rollup/plugin-node-resolve": "^13.2.1", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@rollup/plugin-virtual": "^2.1.0", "@types/chai": "^4.3.1", "@types/mocha": "^9.1.1", diff --git a/packages/lit-starter-js/package.json b/packages/lit-starter-js/package.json index 700e389d43..190fd2cce8 100644 --- a/packages/lit-starter-js/package.json +++ b/packages/lit-starter-js/package.json @@ -48,7 +48,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@web/dev-server": "^0.1.31", "@web/dev-server-legacy": "^1.0.0", "@web/test-runner": "^0.13.27", diff --git a/packages/lit-starter-ts/package.json b/packages/lit-starter-ts/package.json index a17f1f2c6c..6d0df474e4 100644 --- a/packages/lit-starter-ts/package.json +++ b/packages/lit-starter-ts/package.json @@ -49,7 +49,7 @@ "@custom-elements-manifest/analyzer": "^0.6.3", "@open-wc/testing": "^3.1.5", "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^4.0.0", + "@rollup/plugin-replace": "^5.0.2", "@typescript-eslint/eslint-plugin": "^5.25.0", "@typescript-eslint/parser": "^5.25.0", "@web/dev-server": "^0.1.31", diff --git a/packages/reactive-element/package.json b/packages/reactive-element/package.json index 159189f66d..e4487b664d 100644 --- a/packages/reactive-element/package.json +++ b/packages/reactive-element/package.json @@ -166,7 +166,9 @@ "test:dev": "wireit", "test:prod": "wireit", "test:node": "wireit", - "test:node-dev": "wireit" + "test:node-dev": "wireit", + "test:node-dom-shim": "wireit", + "test:node-dom-shim-dev": "wireit" }, "wireit": { "build": { @@ -268,6 +270,8 @@ "test:prod", "test:node", "test:node-dev", + "test:node-dom-shim", + "test:node-dom-shim-dev", "check-version" ] }, @@ -319,6 +323,24 @@ ], "files": [], "output": [] + }, + "test:node-dom-shim": { + "command": "node development/test/node-dom-shim.js", + "dependencies": [ + "build:ts", + "build:rollup" + ], + "files": [], + "output": [] + }, + "test:node-dom-shim-dev": { + "command": "node --conditions=development development/test/node-dom-shim.js", + "dependencies": [ + "build:ts", + "build:rollup" + ], + "files": [], + "output": [] } }, "files": [ diff --git a/packages/reactive-element/src/test/node-dom-shim.ts b/packages/reactive-element/src/test/node-dom-shim.ts new file mode 100644 index 0000000000..ea6457401e --- /dev/null +++ b/packages/reactive-element/src/test/node-dom-shim.ts @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ + +// This file will be loaded by Node from the node:test-dom-shim script to verify +// `ReactiveElement` will prefer extending existing `HTMLElement` from the +// global rather than the built-in shim + +import './node-shim-html-element.js'; +import {ReactiveElement} from '@lit/reactive-element'; +import {HTMLElement} from '@lit-labs/ssr-dom-shim'; + +import assert from 'node:assert/strict'; +assert.strictEqual( + Object.getPrototypeOf(ReactiveElement), + globalThis.HTMLElement, + 'Expected ReactiveElement to extend existing globalThis.HTMLElement' +); +assert.notStrictEqual( + Object.getPrototypeOf(ReactiveElement), + HTMLElement, + 'Expected ReactiveElement to not extend HTMLElement from ssr-dom-shim' +); diff --git a/packages/reactive-element/src/test/node-imports.ts b/packages/reactive-element/src/test/node-imports.ts index 39a58f7760..de5d159206 100644 --- a/packages/reactive-element/src/test/node-imports.ts +++ b/packages/reactive-element/src/test/node-imports.ts @@ -43,3 +43,11 @@ export class MyElement extends ReactiveElement { export class MyOtherElement extends ReactiveElement {} customElements.define('my-other-element', MyOtherElement); + +import assert from 'node:assert/strict'; +import {HTMLElement} from '@lit-labs/ssr-dom-shim'; +assert.strictEqual( + Object.getPrototypeOf(ReactiveElement), + HTMLElement, + 'Expected ReactiveElement to extend HTMLElement from ssr-dom-shim' +); diff --git a/packages/reactive-element/src/test/node-shim-html-element.ts b/packages/reactive-element/src/test/node-shim-html-element.ts new file mode 100644 index 0000000000..94af4df430 --- /dev/null +++ b/packages/reactive-element/src/test/node-shim-html-element.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ + +// This file is used as a side-effectful import in `node-dom-shim.js` to +// simulate loading a separate DOM shim that adds `HTMLElement` to the global + +class FakeHTMLElement {} +globalThis.HTMLElement = FakeHTMLElement as typeof HTMLElement; diff --git a/rollup-common.js b/rollup-common.js index 8366dbfc56..1f07c0fc45 100644 --- a/rollup-common.js +++ b/rollup-common.js @@ -275,6 +275,7 @@ const injectNodeDomShimIntoReactiveElement = [ include: ['**/packages/lit-html/development/experimental-hydrate.js'], }), replace({ + preventAssignment: true, values: { 'extends HTMLElement': 'extends (globalThis.HTMLElement ?? HTMLElement)', },