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:
parent
6faef606d7
commit
2d4d6cbe7b
13 changed files with 90 additions and 63 deletions
|
@ -5,7 +5,7 @@ import jsx from '@astrojs/jsx';
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
jsx(),
|
||||
preact(),
|
||||
jsx()
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import Counter from '../components/Counter';
|
||||
|
||||
const Component = () => {
|
||||
return <div>It works!</div>
|
||||
}
|
||||
|
||||
export default async function Home() {
|
||||
return (
|
||||
<html lang="en">
|
||||
|
@ -10,14 +14,17 @@ export default async function Home() {
|
|||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
<Counter client:load>
|
||||
{/* <Counter client:load>
|
||||
<div>
|
||||
<h1>Hello!</h1>
|
||||
<Counter client:load>
|
||||
<h2>No</h2>
|
||||
<h1>Hello!</h1> */}
|
||||
|
||||
<Component client:idle />
|
||||
|
||||
{/* <Counter client:load>
|
||||
<h2>AHHHHHHHHHH</h2>
|
||||
</Counter>
|
||||
</div>
|
||||
</Counter>
|
||||
</Counter> */}
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
|
|
@ -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))}.
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Fragment } from 'astro/server';
|
||||
import { Fragment } from '../runtime/server/index.js';
|
||||
|
||||
const AstroJSX = Symbol('@astrojs/jsx');
|
||||
|
|
@ -464,7 +464,7 @@ function internalSpreadAttributes(values: Record<any, any>, shouldEscape = true)
|
|||
// Adds support for `<Component {...value} />
|
||||
export function spreadAttributes(
|
||||
values: Record<any, any>,
|
||||
name: string,
|
||||
name?: string,
|
||||
{ class: scopedClassName }: { class?: string } = {}
|
||||
) {
|
||||
let output = '';
|
||||
|
|
41
packages/astro/src/runtime/server/jsx.ts
Normal file
41
packages/astro/src/runtime/server/jsx.ts
Normal 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}>`
|
||||
)}`);
|
||||
}
|
|
@ -17,7 +17,7 @@ const IMPORT_STATEMENTS: Record<string, string> = {
|
|||
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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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' })],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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<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) {
|
||||
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) {}
|
||||
}
|
||||
|
|
|
@ -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']);
|
||||
|
|
Loading…
Reference in a new issue