From e48176a65ea7a80c8ea205b4461b781af6f39327 Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Mon, 31 Oct 2022 15:57:30 -0700 Subject: [PATCH 1/4] Add node build for server rendering --- .eslintignore | 1 + .prettierignore | 1 + packages/labs/react/.gitignore | 1 + packages/labs/react/package.json | 14 +++++++++++- packages/labs/react/rollup.config.js | 1 + packages/labs/react/src/create-component.ts | 8 +++++++ packages/labs/react/src/test/node-render.ts | 25 +++++++++++++++++++++ 7 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 packages/labs/react/src/test/node-render.ts diff --git a/.eslintignore b/.eslintignore index d876a31201..f0da458260 100644 --- a/.eslintignore +++ b/.eslintignore @@ -241,6 +241,7 @@ packages/labs/observers/performance_controller.* packages/labs/observers/resize_controller.* packages/labs/observers/intersection_controller.* packages/labs/react/development/ +packages/labs/react/node/ packages/labs/react/test/ packages/labs/react/node_modules/ packages/labs/react/index.* diff --git a/.prettierignore b/.prettierignore index 5d597b371c..1a006c1203 100644 --- a/.prettierignore +++ b/.prettierignore @@ -227,6 +227,7 @@ packages/labs/observers/performance_controller.* packages/labs/observers/resize_controller.* packages/labs/observers/intersection_controller.* packages/labs/react/development/ +packages/labs/react/node/ packages/labs/react/test/ packages/labs/react/node_modules/ packages/labs/react/index.* diff --git a/packages/labs/react/.gitignore b/packages/labs/react/.gitignore index 3db826b636..9631861522 100644 --- a/packages/labs/react/.gitignore +++ b/packages/labs/react/.gitignore @@ -1,4 +1,5 @@ /development/ +/node/ /test/ /node_modules/ /index.* diff --git a/packages/labs/react/package.json b/packages/labs/react/package.json index 5e3f4faebc..44f0a6ff20 100644 --- a/packages/labs/react/package.json +++ b/packages/labs/react/package.json @@ -20,17 +20,20 @@ ".": { "types": "./development/index.d.ts", "development": "./development/index.js", + "node": "./node/index.js", "default": "./index.js" }, "./use-controller.js": { "types": "./development/use-controller.d.ts", "development": "./development/use-controller.js", + "node": "./node/use-controller.js", "default": "./use-controller.js" } }, "files": [ "/development/", "!/development/test/", + "/node/", "/index.{d.ts,d.ts.map,js,js.map}", "/create-component.{d.ts,d.ts.map,js,js.map}", "/use-controller.{d.ts,d.ts.map,js,js.map}" @@ -43,6 +46,7 @@ "test": "wireit", "test:dev": "wireit", "test:prod": "wireit", + "test:node": "wireit", "checksize": "wireit" }, "wireit": { @@ -111,7 +115,8 @@ "test": { "dependencies": [ "test:dev", - "test:prod" + "test:prod", + "test:node" ] }, "test:dev": { @@ -133,6 +138,13 @@ ], "files": [], "output": [] + }, + "test:node": { + "command": "node development/test/node-render.js", + "dependencies": [ + "build:ts", + "build:rollup" + ] } }, "author": "Google LLC", diff --git a/packages/labs/react/rollup.config.js b/packages/labs/react/rollup.config.js index 57aeba4691..f842d0af20 100644 --- a/packages/labs/react/rollup.config.js +++ b/packages/labs/react/rollup.config.js @@ -10,4 +10,5 @@ import {createRequire} from 'module'; export default litProdConfig({ packageName: createRequire(import.meta.url)('./package.json').name, entryPoints: ['index', 'create-component', 'use-controller'], + includeNodeBuild: true, }); diff --git a/packages/labs/react/src/create-component.ts b/packages/labs/react/src/create-component.ts index 3db9fdca09..367b9a72de 100644 --- a/packages/labs/react/src/create-component.ts +++ b/packages/labs/react/src/create-component.ts @@ -4,6 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ +const NODE_MODE = false; +const global = NODE_MODE ? globalThis : window; + +const htmlElementShimNeeded = NODE_MODE && global.HTMLElement === undefined; +if (htmlElementShimNeeded) { + global.HTMLElement = class HTMLElement {} as unknown as typeof HTMLElement; +} + // Match a prop name to a typed event callback by // adding an Event type as an expected property on a string. export type EventName = string & { diff --git a/packages/labs/react/src/test/node-render.ts b/packages/labs/react/src/test/node-render.ts new file mode 100644 index 0000000000..a04574b461 --- /dev/null +++ b/packages/labs/react/src/test/node-render.ts @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2022 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ + +// This file will be loaded by Node from the node:test script to verify that +// wrapped components can be server rendered by React. + +import {createComponent} from '@lit-labs/react'; +import {ReactiveElement} from '@lit/reactive-element'; +import {customElement} from '@lit/reactive-element/decorators/custom-element.js'; +import React from 'react'; +import {renderToString} from 'react-dom/server.js'; + +@customElement('my-element') +class MyElement extends ReactiveElement {} + +const Component = createComponent({ + react: React, + tagName: 'my-element', + elementClass: MyElement, +}); + +renderToString(React.createElement(Component)); From 1577bb4e34e5ef0572a8c9bf57f7598da71c1e69 Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Mon, 31 Oct 2022 15:59:20 -0700 Subject: [PATCH 2/4] Add changeset --- .changeset/eight-elephants-sparkle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eight-elephants-sparkle.md diff --git a/.changeset/eight-elephants-sparkle.md b/.changeset/eight-elephants-sparkle.md new file mode 100644 index 0000000000..f931f1d451 --- /dev/null +++ b/.changeset/eight-elephants-sparkle.md @@ -0,0 +1,5 @@ +--- +'@lit-labs/react': minor +--- + +Add Node build for server rendering. This will allow wrapped components to be added to SSR React frameworks like Next.js. From fe450aa4766dbce30dc6abbdfef1b320835f4adf Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Mon, 31 Oct 2022 16:37:17 -0700 Subject: [PATCH 3/4] Don't shim HTMLElement --- packages/labs/react/src/create-component.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/labs/react/src/create-component.ts b/packages/labs/react/src/create-component.ts index 367b9a72de..fd2c8297cd 100644 --- a/packages/labs/react/src/create-component.ts +++ b/packages/labs/react/src/create-component.ts @@ -5,12 +5,6 @@ */ const NODE_MODE = false; -const global = NODE_MODE ? globalThis : window; - -const htmlElementShimNeeded = NODE_MODE && global.HTMLElement === undefined; -if (htmlElementShimNeeded) { - global.HTMLElement = class HTMLElement {} as unknown as typeof HTMLElement; -} // Match a prop name to a typed event callback by // adding an Event type as an expected property on a string. @@ -323,7 +317,7 @@ export function createComponent< if ( eventProps.has(k) || (!reservedReactProperties.has(k) && - !(k in HTMLElement.prototype) && + !(NODE_MODE ? false : k in HTMLElement.prototype) && k in element.prototype) ) { this._elementProps[k] = v; From b67c03a165db2a2a63a6a8f8ee4c23300df3fcaf Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Mon, 31 Oct 2022 16:55:28 -0700 Subject: [PATCH 4/4] Check for presence of HTMLElement even in Node --- packages/labs/react/src/create-component.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/labs/react/src/create-component.ts b/packages/labs/react/src/create-component.ts index fd2c8297cd..a439591e46 100644 --- a/packages/labs/react/src/create-component.ts +++ b/packages/labs/react/src/create-component.ts @@ -317,7 +317,11 @@ export function createComponent< if ( eventProps.has(k) || (!reservedReactProperties.has(k) && - !(NODE_MODE ? false : k in HTMLElement.prototype) && + // NODE_MODE check below is to support React SSR where HTMLElement + // might not be defined + !(NODE_MODE && typeof HTMLElement === 'undefined' + ? false + : k in HTMLElement.prototype) && k in element.prototype) ) { this._elementProps[k] = v;