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
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
jsx(),
|
||||||
preact(),
|
preact(),
|
||||||
jsx()
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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))}.
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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 = '';
|
||||||
|
|
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'",
|
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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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' })],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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']);
|
||||||
|
|
Loading…
Reference in a new issue