summaryrefslogtreecommitdiff
path: root/packages/integrations/react/server-v17.js
diff options
context:
space:
mode:
authorGravatar Fred K. Schott <fkschott@gmail.com> 2022-03-31 09:51:29 -0700
committerGravatar GitHub <noreply@github.com> 2022-03-31 12:51:29 -0400
commit57f48b27019bbad5c8d61808291dc8bc6cdedb52 (patch)
tree99c57190e625bdca4c03d86d14795a3a47fd98c3 /packages/integrations/react/server-v17.js
parent25c1abff10a9b46468b750ab967e9b8be44ac38a (diff)
downloadastro-57f48b27019bbad5c8d61808291dc8bc6cdedb52.tar.gz
astro-57f48b27019bbad5c8d61808291dc8bc6cdedb52.tar.zst
astro-57f48b27019bbad5c8d61808291dc8bc6cdedb52.zip
Add support for React 18 in @astrojs/react (#2947)
* First pass at supporting React 18 in @astrojs/react * Try marking React 18’s `react-dom/client` as external * Try a different approach to importing different React versions * Allow resolving JSON modules * Revert "Allow resolving JSON modules" This reverts commit 5279b7249c52b20fd74fe48f9f1047c9b3a117dc. * Try the separate client entrypoint approach from #2946 * Clean up diff * Trying to see something * Just keep swimming… 🐠 * update to support react 18 * add changeset * add docs Co-authored-by: delucis <swithinbank@gmail.com>
Diffstat (limited to 'packages/integrations/react/server-v17.js')
-rw-r--r--packages/integrations/react/server-v17.js67
1 files changed, 67 insertions, 0 deletions
diff --git a/packages/integrations/react/server-v17.js b/packages/integrations/react/server-v17.js
new file mode 100644
index 000000000..1c0c41286
--- /dev/null
+++ b/packages/integrations/react/server-v17.js
@@ -0,0 +1,67 @@
+import React from 'react';
+import ReactDOM from 'react-dom/server.js';
+import StaticHtml from './static-html.js';
+
+const reactTypeof = Symbol.for('react.element');
+
+function errorIsComingFromPreactComponent(err) {
+ return err.message && (err.message.startsWith("Cannot read property '__H'") || err.message.includes("(reading '__H')"));
+}
+
+function check(Component, props, children) {
+ // Note: there are packages that do some unholy things to create "components".
+ // Checking the $$typeof property catches most of these patterns.
+ if (typeof Component === 'object') {
+ const $$typeof = Component['$$typeof'];
+ return $$typeof && $$typeof.toString().slice('Symbol('.length).startsWith('react');
+ }
+ if (typeof Component !== 'function') return false;
+
+ if (Component.prototype != null && typeof Component.prototype.render === 'function') {
+ return React.Component.isPrototypeOf(Component) || React.PureComponent.isPrototypeOf(Component);
+ }
+
+ let error = null;
+ let isReactComponent = false;
+ function Tester(...args) {
+ try {
+ const vnode = Component(...args);
+ if (vnode && vnode['$$typeof'] === reactTypeof) {
+ isReactComponent = true;
+ }
+ } catch (err) {
+ if (!errorIsComingFromPreactComponent(err)) {
+ error = err;
+ }
+ }
+
+ return React.createElement('div');
+ }
+
+ renderToStaticMarkup(Tester, props, children, {});
+
+ if (error) {
+ throw error;
+ }
+ return isReactComponent;
+}
+
+function renderToStaticMarkup(Component, props, children, metadata) {
+ delete props['class'];
+ const vnode = React.createElement(Component, {
+ ...props,
+ children: children != null ? React.createElement(StaticHtml, { value: children }) : undefined,
+ });
+ let html;
+ if (metadata && metadata.hydrate) {
+ html = ReactDOM.renderToString(vnode);
+ } else {
+ html = ReactDOM.renderToStaticMarkup(vnode);
+ }
+ return { html };
+}
+
+export default {
+ check,
+ renderToStaticMarkup,
+};