summaryrefslogtreecommitdiff
path: root/packages/renderers/renderer-react/server.js
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@matthewphillips.info> 2021-06-14 08:35:25 -0400
committerGravatar GitHub <noreply@github.com> 2021-06-14 08:35:25 -0400
commit271cfe6ce33fc6d47f3af15ab8c195560a083f75 (patch)
tree9ff6f52f57e7ab1a60013032065ab3595ccfa357 /packages/renderers/renderer-react/server.js
parentab2972be83a77fabf71ada55a56a26af15d79cef (diff)
downloadastro-271cfe6ce33fc6d47f3af15ab8c195560a083f75.tar.gz
astro-271cfe6ce33fc6d47f3af15ab8c195560a083f75.tar.zst
astro-271cfe6ce33fc6d47f3af15ab8c195560a083f75.zip
Improved JSX framework detection (#382)
* Improved JSX framework detection This improves the JSX detection and adds a bunch of test. The following is improved: * If an error throws because of a coding mistake, those errors will be reported. * We properly detect class components for both Preact and React. We don't have to "try to render" these. It's still possible that error messages might be obscured in this scenario: A Preact function component that uses hooks (or another preact specific feature) that has a coding mistake. The React renderer might throw when it uses the Preact hook. That error will be reported rather than the real coding mistake. This is because we can't distinguish between errors that are due to the wrong framework and errors that the user caused. I might reach out to the Preact community and see if they can think of a better solution to this problem. This will come up when other JSX based frameworks have renderers. I still think that having multiple frameworks in the same project is a feature worth trying to preserve. * Move try/catch into the __astro_component
Diffstat (limited to 'packages/renderers/renderer-react/server.js')
-rw-r--r--packages/renderers/renderer-react/server.js36
1 files changed, 30 insertions, 6 deletions
diff --git a/packages/renderers/renderer-react/server.js b/packages/renderers/renderer-react/server.js
index 56f2f5aa8..8ac177c7c 100644
--- a/packages/renderers/renderer-react/server.js
+++ b/packages/renderers/renderer-react/server.js
@@ -1,13 +1,37 @@
-import { createElement as h } from 'react';
+import { Component as BaseComponent, createElement as h } from 'react';
import { renderToStaticMarkup as renderToString } from 'react-dom/server.js';
import StaticHtml from './static-html.js';
+const reactTypeof = Symbol.for('react.element');
+
function check(Component, props, children) {
- try {
- const { html } = renderToStaticMarkup(Component, props, children);
- return Boolean(html);
- } catch (e) {}
- return false;
+ if(typeof Component !== 'function') return false;
+
+ if(typeof Component.prototype.render === 'function') {
+ return BaseComponent.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) {
+ error = err;
+ }
+
+ return h('div');
+ }
+
+ renderToStaticMarkup(Tester, props, children);
+
+ if(error) {
+ throw error;
+ }
+ return isReactComponent;
}
function renderToStaticMarkup(Component, props, children) {