From b1b5072b6009a5b4246a55daffd1c5a98fa05780 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Tue, 28 Jun 2022 21:02:28 -0400 Subject: [PATCH] feat: add experimental jsx support --- packages/astro/src/core/config.ts | 12 ++++++++---- packages/astro/src/core/render/core.ts | 8 +------- packages/astro/src/runtime/server/index.ts | 17 ++++++++++++++++- packages/astro/src/vite-plugin-jsx/index.ts | 4 ++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index 4ad099e1f7..272c0055ca 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -52,6 +52,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = { experimental: { ssr: false, integrations: false, + jsx: false, }, }; @@ -224,6 +225,7 @@ export const AstroConfigSchema = z.object({ .object({ ssr: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.ssr), integrations: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.integrations), + jsx: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.jsx), }) .optional() .default({}), @@ -339,20 +341,22 @@ export async function validateConfig( const result = { ...(await AstroConfigRelativeSchema.parseAsync(userConfig)), _ctx: { - pageExtensions: [], + pageExtensions: [] as string[], scripts: [], renderers: [], injectedRoutes: [], adapter: undefined, }, }; + if (result.experimental.jsx) { + result._ctx.pageExtensions.push('.jsx', '.tsx'); + } if ( - // TODO: expose @astrojs/mdx package - result.integrations.find((integration) => integration.name === '@astrojs/mdx') + result.experimental.jsx || result.integrations.find((integration) => integration.name === '@astrojs/mdx') ) { // Enable default JSX integration const { default: jsxRenderer } = await import('../jsx/renderer.js'); - (result._ctx.renderers as any[]).push(jsxRenderer); + (result._ctx.renderers as any[]).unshift(jsxRenderer); } // Final-Pass Validation (perform checks that require the full config object) diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index 2487a79e41..ce06968c00 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -140,11 +140,5 @@ export async function render(opts: RenderOptions): Promise { ssr, }); - if (!Component.isAstroComponentFactory) { - const props: Record = { ...(pageProps ?? {}), 'server:root': true }; - const html = await renderComponent(result, Component.name, Component, props, null); - return new Response(html.toString(), result.response); - } else { - return await renderPage(result, Component, pageProps, null); - } + return await renderPage(result, Component, pageProps, null); } diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 8df0440c48..cd7041588d 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -694,10 +694,25 @@ export async function renderPage( props: any, children: any ): Promise { + let iterable: AsyncIterable; + if (!componentFactory.isAstroComponentFactory) { + const pageProps: Record = { ...(props ?? {}), 'server:root': true }; + const output = await renderComponent(result, componentFactory.name, componentFactory, pageProps, null); + let html = output.toString() + if (!/\n${await maybeRenderHead(result)}${html}`; + } + return new Response(html, { + headers: new Headers([ + ['Content-Type', 'text/html; charset=utf-8'], + ['Content-Length', `${Buffer.byteLength(html, 'utf-8')}`] + ]) + }); + } const factoryReturnValue = await componentFactory(result, props, children); if (isAstroComponent(factoryReturnValue)) { - let iterable = renderAstroComponent(factoryReturnValue); + iterable = renderAstroComponent(factoryReturnValue); let stream = new ReadableStream({ start(controller) { async function read() { diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts index 421c3622c1..12d949e603 100644 --- a/packages/astro/src/vite-plugin-jsx/index.ts +++ b/packages/astro/src/vite-plugin-jsx/index.ts @@ -176,6 +176,10 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin } } + if (!importSource && config.experimental.jsx && jsxRenderers.has('astro')) { + importSource = 'astro'; + } + // if JSX renderer found, then use that if (importSource) { const jsxRenderer = jsxRenderers.get(importSource);