From 2d4d6cbe7b12f376e2473fa8f28a71e73fad85c2 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Fri, 17 Jun 2022 12:44:22 -0500 Subject: [PATCH] chore: move `jsx-runtime` to `astro` --- examples/jsx/astro.config.mjs | 2 +- examples/jsx/src/pages/index.jsx | 17 +++++-- examples/mdx/src/pages/index.mdx | 21 +++++++- packages/astro/package.json | 1 + .../jsx => astro}/src/jsx-runtime/index.ts | 2 +- packages/astro/src/runtime/server/index.ts | 2 +- packages/astro/src/runtime/server/jsx.ts | 41 +++++++++++++++ packages/astro/src/vite-plugin-jsx/index.ts | 6 +-- packages/integrations/jsx/package.json | 1 - packages/integrations/jsx/src/babel/index.ts | 4 +- packages/integrations/jsx/src/index.ts | 4 +- packages/integrations/jsx/src/server.ts | 50 ++----------------- packages/integrations/mdx/src/index.ts | 2 +- 13 files changed, 90 insertions(+), 63 deletions(-) rename packages/{integrations/jsx => astro}/src/jsx-runtime/index.ts (84%) create mode 100644 packages/astro/src/runtime/server/jsx.ts diff --git a/examples/jsx/astro.config.mjs b/examples/jsx/astro.config.mjs index 19977ef60e..6a101ede97 100644 --- a/examples/jsx/astro.config.mjs +++ b/examples/jsx/astro.config.mjs @@ -5,7 +5,7 @@ import jsx from '@astrojs/jsx'; // https://astro.build/config export default defineConfig({ integrations: [ + jsx(), preact(), - jsx() ] }); diff --git a/examples/jsx/src/pages/index.jsx b/examples/jsx/src/pages/index.jsx index 9679e30ea2..cf5fff30a7 100644 --- a/examples/jsx/src/pages/index.jsx +++ b/examples/jsx/src/pages/index.jsx @@ -1,5 +1,9 @@ import Counter from '../components/Counter'; +const Component = () => { + return
It works!
+} + export default async function Home() { return ( @@ -10,14 +14,17 @@ export default async function Home() {

Astro

- + {/*
-

Hello!

- -

No

+

Hello!

*/} + + + + {/* +

AHHHHHHHHHH

-
+
*/} ) diff --git a/examples/mdx/src/pages/index.mdx b/examples/mdx/src/pages/index.mdx index 9f599fb6aa..1fcfb3ddd5 100644 --- a/examples/mdx/src/pages/index.mdx +++ b/examples/mdx/src/pages/index.mdx @@ -1,10 +1,27 @@ -# Hello world! - +import Heading from '../components/MyHeading.astro' export const authors = [ {name: 'Jane', email: 'hi@jane.com'}, {name: 'John', twitter: '@john2002'} ] export const published = new Date('2022-02-01') +export const components = { h1: Heading } + +# Hello world! + +Text that is not a quote + +> Text that is a quote + +Use `git status` to list all new or modified files that haven't yet been committed. + +Some basic Git commands are: +``` +git status +git add +git commit +``` + +This site was built using [GitHub Pages](https://pages.github.com/). Written by: {new Intl.ListFormat('en').format(authors.map(d => d.name))}. diff --git a/packages/astro/package.json b/packages/astro/package.json index e60c961991..14e77fa031 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -30,6 +30,7 @@ ".": "./astro.js", "./env": "./env.d.ts", "./astro-jsx": "./astro-jsx.d.ts", + "./jsx-runtime": "./dist/jsx-runtime/index.js", "./config": "./config.mjs", "./app": "./dist/core/app/index.js", "./app/node": "./dist/core/app/node.js", diff --git a/packages/integrations/jsx/src/jsx-runtime/index.ts b/packages/astro/src/jsx-runtime/index.ts similarity index 84% rename from packages/integrations/jsx/src/jsx-runtime/index.ts rename to packages/astro/src/jsx-runtime/index.ts index 502ffeb999..da2da3b220 100644 --- a/packages/integrations/jsx/src/jsx-runtime/index.ts +++ b/packages/astro/src/jsx-runtime/index.ts @@ -1,4 +1,4 @@ -import { Fragment } from 'astro/server'; +import { Fragment } from '../runtime/server/index.js'; const AstroJSX = Symbol('@astrojs/jsx'); diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 61469ae03e..709c9c36f4 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -464,7 +464,7 @@ function internalSpreadAttributes(values: Record, shouldEscape = true) // Adds support for ` export function spreadAttributes( values: Record, - name: string, + name?: string, { class: scopedClassName }: { class?: string } = {} ) { let output = ''; diff --git a/packages/astro/src/runtime/server/jsx.ts b/packages/astro/src/runtime/server/jsx.ts new file mode 100644 index 0000000000..2ef1e652cd --- /dev/null +++ b/packages/astro/src/runtime/server/jsx.ts @@ -0,0 +1,41 @@ +import { HTMLString, markHTMLString, escapeHTML, Fragment, renderComponent, spreadAttributes, voidElementNames } from './index.js'; +import { jsx, AstroJSX } from '../../jsx-runtime/index.js'; + +export async function renderJSX(result: any, vnode: any): Promise { + switch (true) { + case (vnode instanceof HTMLString): return vnode; + case (typeof vnode === 'string'): return markHTMLString(escapeHTML(vnode)); + case (!vnode && vnode !== 0): return ''; + case (vnode.type === Fragment): return renderJSX(result, vnode.props.children); + case (Array.isArray(vnode)): return markHTMLString((await Promise.all(vnode.map((v: any) => renderJSX(result, v)))).join('')); + } + if (vnode[AstroJSX]) { + if (!vnode.type && vnode.type !== 0) return ''; + if (typeof vnode.type === 'string') { + return await renderElement(result, vnode.type, vnode.props ?? {}); + } + if (typeof vnode.type === 'function') { + try { + const output = await vnode.type(vnode.props ?? {}); + return await renderJSX(result, output); + } catch (e) {} + + const { children = null, ...props } = vnode.props ?? {}; + const slots: Record = {} + if (children) { + slots.default = () => renderJSX(result, jsx(Fragment, { children })) + } + return markHTMLString(await renderComponent(result, vnode.type.name, vnode.type, props, slots)); + } + } + // numbers, plain objects, etc + return markHTMLString(`${vnode}`); +} + +async function renderElement(result: any, tag: string, { children, ...props }: Record) { + return markHTMLString(`<${tag}${spreadAttributes(props)}${markHTMLString( + (children == null || children == '') && voidElementNames.test(tag) + ? `/>` + : `>${children == null ? '' : await renderJSX(result, children)}${tag === 'head' ? '' : ''}` + )}`); +} diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts index 15a9006858..e993af64d6 100644 --- a/packages/astro/src/vite-plugin-jsx/index.ts +++ b/packages/astro/src/vite-plugin-jsx/index.ts @@ -17,7 +17,7 @@ const IMPORT_STATEMENTS: Record = { react: "import React from 'react'", preact: "import { h } from 'preact'", 'solid-js': "import 'solid-js/web'", - astro: "import '@astrojs/jsx'", + astro: "import 'astro'", }; // A code snippet to inject into JS files to prevent esbuild reference bugs. @@ -177,8 +177,8 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin } } - if (!importSource && jsxRenderers.has('@astrojs/jsx')) { - importSource = '@astrojs/jsx'; + if (!importSource && jsxRenderers.has('astro')) { + importSource = 'astro'; } // if JSX renderer found, then use that diff --git a/packages/integrations/jsx/package.json b/packages/integrations/jsx/package.json index 6d6f5e86b4..91efaa4e0a 100644 --- a/packages/integrations/jsx/package.json +++ b/packages/integrations/jsx/package.json @@ -21,7 +21,6 @@ "exports": { ".": "./dist/index.js", "./babel": "./dist/babel/index.js", - "./jsx-runtime": "./dist/jsx-runtime/index.js", "./client.js": "./dist/client.js", "./server.js": "./dist/server.js", "./package.json": "./package.json" diff --git a/packages/integrations/jsx/src/babel/index.ts b/packages/integrations/jsx/src/babel/index.ts index 8c8d3029a8..6705a9f062 100644 --- a/packages/integrations/jsx/src/babel/index.ts +++ b/packages/integrations/jsx/src/babel/index.ts @@ -69,7 +69,7 @@ export default function astroJSX(): PluginObj { visitor: { ImportDeclaration(path, state) { const source = path.node.source.value; - if (source.startsWith('@astrojs/jsx')) return; + if (source.startsWith('astro/jsx-runtime')) return; const specs = path.node.specifiers.map(spec => { if (t.isImportDefaultSpecifier(spec)) return { local: spec.local.name, imported: 'default' } if (t.isImportNamespaceSpecifier(spec)) return { local: spec.local.name, imported: '*' } @@ -110,6 +110,8 @@ export default function astroJSX(): PluginObj { const meta = path.getData('import'); if (meta) { addClientMetadata(parentNode, meta) + } else { + console.warn(getTagName(parentNode)) } }, } diff --git a/packages/integrations/jsx/src/index.ts b/packages/integrations/jsx/src/index.ts index d509d96003..9d34b117e2 100644 --- a/packages/integrations/jsx/src/index.ts +++ b/packages/integrations/jsx/src/index.ts @@ -5,12 +5,12 @@ function getRenderer() { name: '@astrojs/jsx', clientEntrypoint: '@astrojs/jsx/client.js', serverEntrypoint: '@astrojs/jsx/server.js', - jsxImportSource: '@astrojs/jsx', + jsxImportSource: 'astro', jsxTransformOptions: async () => { const { default: { default: jsx } } = await import('@babel/plugin-transform-react-jsx'); const { default: astroJSX } = await import('./babel/index.js'); return { - plugins: [astroJSX(), jsx({ }, { throwIfNamespace: false, runtime: 'automatic', importSource: '@astrojs/jsx' })], + plugins: [astroJSX(), jsx({ }, { throwIfNamespace: false, runtime: 'automatic', importSource: 'astro' })], }; }, }; diff --git a/packages/integrations/jsx/src/server.ts b/packages/integrations/jsx/src/server.ts index 1b84643611..530c38f583 100644 --- a/packages/integrations/jsx/src/server.ts +++ b/packages/integrations/jsx/src/server.ts @@ -1,47 +1,7 @@ -import { Fragment, renderComponent, spreadAttributes, markHTMLString, escapeHTML, HTMLString, voidElementNames } from 'astro/server'; -import { AstroJSX, jsx } from './jsx-runtime'; +import { renderJSX } from 'astro/server/jsx.js'; +import { AstroJSX, jsx } from 'astro/jsx-runtime'; -async function render(result: any, vnode: any): Promise { - switch (true) { - case (vnode instanceof HTMLString): return vnode; - case (typeof vnode === 'string'): return markHTMLString(escapeHTML(vnode)); - case (!vnode && vnode !== 0): return ''; - case (vnode.type === Fragment): return render(result, vnode.props.children); - case (Array.isArray(vnode)): return markHTMLString((await Promise.all(vnode.map((v: any) => render(result, v)))).join('')); - // case (typeof vnode === 'object'): return vnode ? markHTMLString(`${vnode}`) : ''; - } - if (vnode[AstroJSX]) { - if (!vnode.type && vnode.type !== 0) return ''; - if (typeof vnode.type === 'string') { - return await renderElement(result, vnode.type, vnode.props ?? {}); - } - if (typeof vnode.type === 'function') { - try { - const output = await vnode.type(vnode.props ?? {}); - return await render(result, output); - } catch (e) {} - - const { children = null, ...props } = vnode.props ?? {}; - const slots: Record = {} - if (children) { - slots.default = () => render(result, jsx(Fragment, { children })) - } - return markHTMLString(await renderComponent(result, vnode.type.name, vnode.type, props, slots)); - } - } - // numbers, plain objects, etc - return markHTMLString(`${vnode}`); -} - -async function renderElement(result: any, tag: string, { children, ...props }: Record) { - return markHTMLString(`<${tag}${spreadAttributes(props)}${markHTMLString( - (children == null || children == '') && voidElementNames.test(tag) - ? `/>` - : `>${children == null ? '' : await render(result, children)}${tag === 'head' ? '' : ''}` - )}`); -} - -export async function check(Component, props, children) { +export async function check(Component: any, props: any, children: any) { if (typeof Component !== 'function') return false; try { const result = await Component({ ...props, children }); @@ -50,10 +10,10 @@ export async function check(Component, props, children) { return false; } -export async function renderToStaticMarkup(this: any, Component, props = {}, children = null) { +export async function renderToStaticMarkup(this: any, Component: any, props = {}, children = null) { const { result } = this; try { - const html = await render(result, jsx(Component, { children, ...props })); + const html = await renderJSX(result, jsx(Component, { children, ...props })); return { html }; } catch (e) {} } diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index b5df122ec4..f1fc53ca71 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -10,7 +10,7 @@ export default function (): AstroIntegration { 'astro:config:setup': ({ updateConfig, addPageExtensions }) => { const mdxPlugin = mdx({ jsx: true, - 'jsxImportSource': '@astrojs/jsx' + 'jsxImportSource': 'astro' }) addPageExtensions(['.mdx']);