0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

chore: move jsx-runtime to astro

This commit is contained in:
Nate Moore 2022-06-17 12:44:22 -05:00
parent 6faef606d7
commit 2d4d6cbe7b
13 changed files with 90 additions and 63 deletions

View file

@ -5,7 +5,7 @@ import jsx from '@astrojs/jsx';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
integrations: [ integrations: [
jsx(),
preact(), preact(),
jsx()
] ]
}); });

View file

@ -1,5 +1,9 @@
import Counter from '../components/Counter'; import Counter from '../components/Counter';
const Component = () => {
return <div>It works!</div>
}
export default async function Home() { export default async function Home() {
return ( return (
<html lang="en"> <html lang="en">
@ -10,14 +14,17 @@ export default async function Home() {
</head> </head>
<body> <body>
<h1>Astro</h1> <h1>Astro</h1>
<Counter client:load> {/* <Counter client:load>
<div> <div>
<h1>Hello!</h1> <h1>Hello!</h1> */}
<Counter client:load>
<h2>No</h2> <Component client:idle />
{/* <Counter client:load>
<h2>AHHHHHHHHHH</h2>
</Counter> </Counter>
</div> </div>
</Counter> </Counter> */}
</body> </body>
</html> </html>
) )

View file

@ -1,10 +1,27 @@
# Hello world! import Heading from '../components/MyHeading.astro'
export const authors = [ export const authors = [
{name: 'Jane', email: 'hi@jane.com'}, {name: 'Jane', email: 'hi@jane.com'},
{name: 'John', twitter: '@john2002'} {name: 'John', twitter: '@john2002'}
] ]
export const published = new Date('2022-02-01') 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))}. Written by: {new Intl.ListFormat('en').format(authors.map(d => d.name))}.

View file

@ -30,6 +30,7 @@
".": "./astro.js", ".": "./astro.js",
"./env": "./env.d.ts", "./env": "./env.d.ts",
"./astro-jsx": "./astro-jsx.d.ts", "./astro-jsx": "./astro-jsx.d.ts",
"./jsx-runtime": "./dist/jsx-runtime/index.js",
"./config": "./config.mjs", "./config": "./config.mjs",
"./app": "./dist/core/app/index.js", "./app": "./dist/core/app/index.js",
"./app/node": "./dist/core/app/node.js", "./app/node": "./dist/core/app/node.js",

View file

@ -1,4 +1,4 @@
import { Fragment } from 'astro/server'; import { Fragment } from '../runtime/server/index.js';
const AstroJSX = Symbol('@astrojs/jsx'); const AstroJSX = Symbol('@astrojs/jsx');

View file

@ -464,7 +464,7 @@ function internalSpreadAttributes(values: Record<any, any>, shouldEscape = true)
// Adds support for `<Component {...value} /> // Adds support for `<Component {...value} />
export function spreadAttributes( export function spreadAttributes(
values: Record<any, any>, values: Record<any, any>,
name: string, name?: string,
{ class: scopedClassName }: { class?: string } = {} { class: scopedClassName }: { class?: string } = {}
) { ) {
let output = ''; let output = '';

View file

@ -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<any> {
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<string, any> = {}
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<string, any>) {
return markHTMLString(`<${tag}${spreadAttributes(props)}${markHTMLString(
(children == null || children == '') && voidElementNames.test(tag)
? `/>`
: `>${children == null ? '' : await renderJSX(result, children)}${tag === 'head' ? '<!--astro:head-->' : ''}</${tag}>`
)}`);
}

View file

@ -17,7 +17,7 @@ const IMPORT_STATEMENTS: Record<string, string> = {
react: "import React from 'react'", react: "import React from 'react'",
preact: "import { h } from 'preact'", preact: "import { h } from 'preact'",
'solid-js': "import 'solid-js/web'", '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. // 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')) { if (!importSource && jsxRenderers.has('astro')) {
importSource = '@astrojs/jsx'; importSource = 'astro';
} }
// if JSX renderer found, then use that // if JSX renderer found, then use that

View file

@ -21,7 +21,6 @@
"exports": { "exports": {
".": "./dist/index.js", ".": "./dist/index.js",
"./babel": "./dist/babel/index.js", "./babel": "./dist/babel/index.js",
"./jsx-runtime": "./dist/jsx-runtime/index.js",
"./client.js": "./dist/client.js", "./client.js": "./dist/client.js",
"./server.js": "./dist/server.js", "./server.js": "./dist/server.js",
"./package.json": "./package.json" "./package.json": "./package.json"

View file

@ -69,7 +69,7 @@ export default function astroJSX(): PluginObj {
visitor: { visitor: {
ImportDeclaration(path, state) { ImportDeclaration(path, state) {
const source = path.node.source.value; 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 => { const specs = path.node.specifiers.map(spec => {
if (t.isImportDefaultSpecifier(spec)) return { local: spec.local.name, imported: 'default' } if (t.isImportDefaultSpecifier(spec)) return { local: spec.local.name, imported: 'default' }
if (t.isImportNamespaceSpecifier(spec)) return { local: spec.local.name, imported: '*' } if (t.isImportNamespaceSpecifier(spec)) return { local: spec.local.name, imported: '*' }
@ -110,6 +110,8 @@ export default function astroJSX(): PluginObj {
const meta = path.getData('import'); const meta = path.getData('import');
if (meta) { if (meta) {
addClientMetadata(parentNode, meta) addClientMetadata(parentNode, meta)
} else {
console.warn(getTagName(parentNode))
} }
}, },
} }

View file

@ -5,12 +5,12 @@ function getRenderer() {
name: '@astrojs/jsx', name: '@astrojs/jsx',
clientEntrypoint: '@astrojs/jsx/client.js', clientEntrypoint: '@astrojs/jsx/client.js',
serverEntrypoint: '@astrojs/jsx/server.js', serverEntrypoint: '@astrojs/jsx/server.js',
jsxImportSource: '@astrojs/jsx', jsxImportSource: 'astro',
jsxTransformOptions: async () => { jsxTransformOptions: async () => {
const { default: { default: jsx } } = await import('@babel/plugin-transform-react-jsx'); const { default: { default: jsx } } = await import('@babel/plugin-transform-react-jsx');
const { default: astroJSX } = await import('./babel/index.js'); const { default: astroJSX } = await import('./babel/index.js');
return { return {
plugins: [astroJSX(), jsx({ }, { throwIfNamespace: false, runtime: 'automatic', importSource: '@astrojs/jsx' })], plugins: [astroJSX(), jsx({ }, { throwIfNamespace: false, runtime: 'automatic', importSource: 'astro' })],
}; };
}, },
}; };

View file

@ -1,47 +1,7 @@
import { Fragment, renderComponent, spreadAttributes, markHTMLString, escapeHTML, HTMLString, voidElementNames } from 'astro/server'; import { renderJSX } from 'astro/server/jsx.js';
import { AstroJSX, jsx } from './jsx-runtime'; import { AstroJSX, jsx } from 'astro/jsx-runtime';
async function render(result: any, vnode: any): Promise<any> { export async function check(Component: any, props: any, children: any) {
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<string, any> = {}
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<string, any>) {
return markHTMLString(`<${tag}${spreadAttributes(props)}${markHTMLString(
(children == null || children == '') && voidElementNames.test(tag)
? `/>`
: `>${children == null ? '' : await render(result, children)}${tag === 'head' ? '<!--astro:head-->' : ''}</${tag}>`
)}`);
}
export async function check(Component, props, children) {
if (typeof Component !== 'function') return false; if (typeof Component !== 'function') return false;
try { try {
const result = await Component({ ...props, children }); const result = await Component({ ...props, children });
@ -50,10 +10,10 @@ export async function check(Component, props, children) {
return false; 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; const { result } = this;
try { try {
const html = await render(result, jsx(Component, { children, ...props })); const html = await renderJSX(result, jsx(Component, { children, ...props }));
return { html }; return { html };
} catch (e) {} } catch (e) {}
} }

View file

@ -10,7 +10,7 @@ export default function (): AstroIntegration {
'astro:config:setup': ({ updateConfig, addPageExtensions }) => { 'astro:config:setup': ({ updateConfig, addPageExtensions }) => {
const mdxPlugin = mdx({ const mdxPlugin = mdx({
jsx: true, jsx: true,
'jsxImportSource': '@astrojs/jsx' 'jsxImportSource': 'astro'
}) })
addPageExtensions(['.mdx']); addPageExtensions(['.mdx']);