feat: add experimental jsx support

This commit is contained in:
Nate Moore 2022-06-28 21:02:28 -04:00
parent 660abd3dee
commit b1b5072b60
4 changed files with 29 additions and 12 deletions

View file

@ -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)

View file

@ -140,11 +140,5 @@ export async function render(opts: RenderOptions): Promise<Response> {
ssr,
});
if (!Component.isAstroComponentFactory) {
const props: Record<string, any> = { ...(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);
}
}

View file

@ -694,10 +694,25 @@ export async function renderPage(
props: any,
children: any
): Promise<Response> {
let iterable: AsyncIterable<any>;
if (!componentFactory.isAstroComponentFactory) {
const pageProps: Record<string, any> = { ...(props ?? {}), 'server:root': true };
const output = await renderComponent(result, componentFactory.name, componentFactory, pageProps, null);
let html = output.toString()
if (!/<!doctype html/i.test(html)) {
html = `<!DOCTYPE html>\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() {

View file

@ -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);