[ci] yarn format
This commit is contained in:
parent
bd18e14a2c
commit
561cbee68f
16 changed files with 82 additions and 87 deletions
|
@ -79,11 +79,13 @@ export default {
|
||||||
Astro is unique in that it allows you to mix multiple types of JSX/TSX files in a single project. It does this by reading the `jsxImportSource` and `jsxTransformOptions` from renderers and transforming a file with [Babel](https://babeljs.io/).
|
Astro is unique in that it allows you to mix multiple types of JSX/TSX files in a single project. It does this by reading the `jsxImportSource` and `jsxTransformOptions` from renderers and transforming a file with [Babel](https://babeljs.io/).
|
||||||
|
|
||||||
#### `jsxImportSource`
|
#### `jsxImportSource`
|
||||||
|
|
||||||
This is the name of your library (for example `preact` or `react` or `solid-js`) which, if encountered in a file, will signal to Astro that this renderer should be used.
|
This is the name of your library (for example `preact` or `react` or `solid-js`) which, if encountered in a file, will signal to Astro that this renderer should be used.
|
||||||
|
|
||||||
Users may also manually define `/** @jsxImportSource preact */` in to ensure that the file is processed by this renderer (if, for example, the file has no imports).
|
Users may also manually define `/** @jsxImportSource preact */` in to ensure that the file is processed by this renderer (if, for example, the file has no imports).
|
||||||
|
|
||||||
#### `jsxTransformOptions`
|
#### `jsxTransformOptions`
|
||||||
|
|
||||||
This is an `async` function that returns information about how to transform matching JSX files with [Babel](https://babeljs.io/). It supports [`plugins`](https://babeljs.io/docs/en/plugins) or [`presets`](https://babeljs.io/docs/en/presets) to be passed directly to Babel.
|
This is an `async` function that returns information about how to transform matching JSX files with [Babel](https://babeljs.io/). It supports [`plugins`](https://babeljs.io/docs/en/plugins) or [`presets`](https://babeljs.io/docs/en/presets) to be passed directly to Babel.
|
||||||
|
|
||||||
> Keep in mind that this transform doesn't need to handle TSX separately from JSX, Astro handles that for you!
|
> Keep in mind that this transform doesn't need to handle TSX separately from JSX, Astro handles that for you!
|
||||||
|
|
|
@ -11,11 +11,5 @@ export default {
|
||||||
// port: 3000, // The port to run the dev server on.
|
// port: 3000, // The port to run the dev server on.
|
||||||
// tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
|
// tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
|
||||||
},
|
},
|
||||||
renderers: [
|
renderers: ['@astrojs/renderer-preact', '@astrojs/renderer-react', '@astrojs/renderer-svelte', '@astrojs/renderer-vue', '@astrojs/renderer-solid'],
|
||||||
'@astrojs/renderer-preact',
|
|
||||||
'@astrojs/renderer-react',
|
|
||||||
'@astrojs/renderer-svelte',
|
|
||||||
'@astrojs/renderer-vue',
|
|
||||||
'@astrojs/renderer-solid',
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
export default function PreactSFC({ children }) {
|
export default function PreactSFC({ children }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="counter">
|
<div className="counter">Hello from Preact!</div>
|
||||||
Hello from Preact!
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from 'solid-js';
|
||||||
|
|
||||||
/** a counter written with Solid */
|
/** a counter written with Solid */
|
||||||
export default function SolidCounter({ children }) {
|
export default function SolidCounter({ children }) {
|
||||||
|
@ -13,9 +13,7 @@ export default function SolidCounter({ children }) {
|
||||||
<pre>{count()}</pre>
|
<pre>{count()}</pre>
|
||||||
<button onClick={add}>+</button>
|
<button onClick={add}>+</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="children">
|
<div class="children">{children}</div>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,5 @@ export default {
|
||||||
// port: 3000, // The port to run the dev server on.
|
// port: 3000, // The port to run the dev server on.
|
||||||
// tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
|
// tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
|
||||||
},
|
},
|
||||||
renderers: [
|
renderers: ['@astrojs/renderer-solid'],
|
||||||
'@astrojs/renderer-solid'
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from 'solid-js';
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
export default function SolidCounter({ children }) {
|
export default function SolidCounter({ children }) {
|
||||||
|
@ -13,9 +13,7 @@ export default function SolidCounter({ children }) {
|
||||||
<pre>{count()}</pre>
|
<pre>{count()}</pre>
|
||||||
<button onClick={add}>+</button>
|
<button onClick={add}>+</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="children">
|
<div class="children">{children}</div>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ const colors = require('kleur/colors');
|
||||||
const loggerPromise = import('./dist/logger.js');
|
const loggerPromise = import('./dist/logger.js');
|
||||||
const { promises: fs } = require('fs');
|
const { promises: fs } = require('fs');
|
||||||
|
|
||||||
const babel = require('@babel/core')
|
const babel = require('@babel/core');
|
||||||
const eslexer = require('es-module-lexer');
|
const eslexer = require('es-module-lexer');
|
||||||
let error = (...args) => {};
|
let error = (...args) => {};
|
||||||
|
|
||||||
|
@ -27,10 +27,7 @@ function getLoader(fileExt) {
|
||||||
* @type {import('snowpack').SnowpackPluginFactory<PluginOptions>}
|
* @type {import('snowpack').SnowpackPluginFactory<PluginOptions>}
|
||||||
*/
|
*/
|
||||||
module.exports = function jsxPlugin(config, options = {}) {
|
module.exports = function jsxPlugin(config, options = {}) {
|
||||||
const {
|
const { configManager, logging } = options;
|
||||||
configManager,
|
|
||||||
logging,
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
let didInit = false;
|
let didInit = false;
|
||||||
return {
|
return {
|
||||||
|
@ -59,39 +56,47 @@ module.exports = function jsxPlugin(config, options = {}) {
|
||||||
sourcesContent: config.mode !== 'production',
|
sourcesContent: config.mode !== 'production',
|
||||||
});
|
});
|
||||||
for (const warning of warnings) {
|
for (const warning of warnings) {
|
||||||
error(logging, 'renderer', `${colors.bold('!')} ${filePath}
|
error(
|
||||||
${warning.text}`);
|
logging,
|
||||||
|
'renderer',
|
||||||
|
`${colors.bold('!')} ${filePath}
|
||||||
|
${warning.text}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderers = await configManager.getRenderers();
|
let renderers = await configManager.getRenderers();
|
||||||
const importSources = new Set(renderers.map(({ jsxImportSource }) => jsxImportSource).filter(i => i));
|
const importSources = new Set(renderers.map(({ jsxImportSource }) => jsxImportSource).filter((i) => i));
|
||||||
const getRenderer = (importSource) => renderers.find(({ jsxImportSource }) => jsxImportSource === importSource);
|
const getRenderer = (importSource) => renderers.find(({ jsxImportSource }) => jsxImportSource === importSource);
|
||||||
const getTransformOptions = async (importSource) => {
|
const getTransformOptions = async (importSource) => {
|
||||||
const { name } = getRenderer(importSource);
|
const { name } = getRenderer(importSource);
|
||||||
const { default: renderer } = await import(name);
|
const { default: renderer } = await import(name);
|
||||||
return renderer.jsxTransformOptions(transformContext);
|
return renderer.jsxTransformOptions(transformContext);
|
||||||
}
|
};
|
||||||
|
|
||||||
if (importSources.size === 0) {
|
if (importSources.size === 0) {
|
||||||
error(logging, 'renderer', `${colors.yellow(filePath)}
|
error(
|
||||||
Unable to resolve a renderer that handles JSX transforms! Please include a \`renderer\` plugin which supports JSX in your \`astro.config.mjs\` file.`);
|
logging,
|
||||||
|
'renderer',
|
||||||
|
`${colors.yellow(filePath)}
|
||||||
|
Unable to resolve a renderer that handles JSX transforms! Please include a \`renderer\` plugin which supports JSX in your \`astro.config.mjs\` file.`
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'.js': {
|
'.js': {
|
||||||
code: `(() => {
|
code: `(() => {
|
||||||
throw new Error("Hello world!");
|
throw new Error("Hello world!");
|
||||||
})()`
|
})()`,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we only have a single renderer, we can skip a bunch of work!
|
// If we only have a single renderer, we can skip a bunch of work!
|
||||||
if (importSources.size === 1) {
|
if (importSources.size === 1) {
|
||||||
const result = transform(code, filePath, await getTransformOptions(Array.from(importSources)[0]))
|
const result = transform(code, filePath, await getTransformOptions(Array.from(importSources)[0]));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'.js': {
|
'.js': {
|
||||||
code: result.code || ''
|
code: result.code || '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -106,7 +111,7 @@ Unable to resolve a renderer that handles JSX transforms! Please include a \`ren
|
||||||
});
|
});
|
||||||
|
|
||||||
let imports = [];
|
let imports = [];
|
||||||
if (/import/.test(codeToScan)) {
|
if (/import/.test(codeToScan)) {
|
||||||
let [i] = eslexer.parse(codeToScan);
|
let [i] = eslexer.parse(codeToScan);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
imports = i;
|
imports = i;
|
||||||
|
@ -138,39 +143,43 @@ Unable to resolve a renderer that handles JSX transforms! Please include a \`ren
|
||||||
|
|
||||||
if (!importSource) {
|
if (!importSource) {
|
||||||
const importStatements = {
|
const importStatements = {
|
||||||
'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'",
|
||||||
}
|
};
|
||||||
if (importSources.size > 1) {
|
if (importSources.size > 1) {
|
||||||
const defaultRenderer = Array.from(importSources)[0];
|
const defaultRenderer = Array.from(importSources)[0];
|
||||||
error(logging, 'renderer', `${colors.yellow(filePath)}
|
error(
|
||||||
|
logging,
|
||||||
|
'renderer',
|
||||||
|
`${colors.yellow(filePath)}
|
||||||
Unable to resolve a renderer that handles this file! With more than one renderer enabled, you should include an import or use a pragma comment.
|
Unable to resolve a renderer that handles this file! With more than one renderer enabled, you should include an import or use a pragma comment.
|
||||||
Add ${colors.cyan(importStatements[defaultRenderer] || `import '${defaultRenderer}';`)} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file.
|
Add ${colors.cyan(importStatements[defaultRenderer] || `import '${defaultRenderer}';`)} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file.
|
||||||
`);
|
`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'.js': {
|
'.js': {
|
||||||
code: contents
|
code: contents,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = transform(code, filePath, await getTransformOptions(importSource));
|
const result = transform(code, filePath, await getTransformOptions(importSource));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'.js': {
|
'.js': {
|
||||||
code: result.code || ''
|
code: result.code || '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
cleanup() {},
|
cleanup() {},
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param code {string}
|
* @param code {string}
|
||||||
* @param id {string}
|
* @param id {string}
|
||||||
* @param opts {{ plugins?: import('@babel/core').PluginItem[], presets?: import('@babel/core').PluginItem[] }|undefined}
|
* @param opts {{ plugins?: import('@babel/core').PluginItem[], presets?: import('@babel/core').PluginItem[] }|undefined}
|
||||||
|
@ -178,7 +187,7 @@ Add ${colors.cyan(importStatements[defaultRenderer] || `import '${defaultRendere
|
||||||
const transform = (code, id, { alias, plugins = [], presets = [] } = {}) =>
|
const transform = (code, id, { alias, plugins = [], presets = [] } = {}) =>
|
||||||
babel.transformSync(code, {
|
babel.transformSync(code, {
|
||||||
presets,
|
presets,
|
||||||
plugins: [...plugins, alias ? ['babel-plugin-module-resolver', { root: process.cwd(), alias }] : undefined].filter(v => v),
|
plugins: [...plugins, alias ? ['babel-plugin-module-resolver', { root: process.cwd(), alias }] : undefined].filter((v) => v),
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
filename: id,
|
filename: id,
|
||||||
ast: false,
|
ast: false,
|
||||||
|
|
|
@ -18,7 +18,9 @@ interface RendererInstance {
|
||||||
polyfills: string[];
|
polyfills: string[];
|
||||||
hydrationPolyfills: string[];
|
hydrationPolyfills: string[];
|
||||||
jsxImportSource?: string;
|
jsxImportSource?: string;
|
||||||
jsxTransformOptions?: (transformContext: Omit<PluginLoadOptions, 'filePath'|'fileExt'>) => undefined|{ plugins?: any[], presets?: any[] }|Promise<{ plugins?: any[], presets?: any[] }>
|
jsxTransformOptions?: (
|
||||||
|
transformContext: Omit<PluginLoadOptions, 'filePath' | 'fileExt'>
|
||||||
|
) => undefined | { plugins?: any[]; presets?: any[] } | Promise<{ plugins?: any[]; presets?: any[] }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONFIG_MODULE_BASE_NAME = '__astro_config.js';
|
const CONFIG_MODULE_BASE_NAME = '__astro_config.js';
|
||||||
|
@ -121,7 +123,7 @@ export class ConfigManager {
|
||||||
external: raw.external,
|
external: raw.external,
|
||||||
polyfills: polyfillsNormalized,
|
polyfills: polyfillsNormalized,
|
||||||
hydrationPolyfills: hydrationPolyfillsNormalized,
|
hydrationPolyfills: hydrationPolyfillsNormalized,
|
||||||
jsxImportSource: raw.jsxImportSource
|
jsxImportSource: raw.jsxImportSource,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO
|
||||||
astroConfig: AstroConfig;
|
astroConfig: AstroConfig;
|
||||||
hmrPort?: number;
|
hmrPort?: number;
|
||||||
mode: RuntimeMode;
|
mode: RuntimeMode;
|
||||||
logging: LogOptions,
|
logging: LogOptions;
|
||||||
configManager: ConfigManager;
|
configManager: ConfigManager;
|
||||||
} = {
|
} = {
|
||||||
astroConfig,
|
astroConfig,
|
||||||
|
|
|
@ -46,10 +46,9 @@ PreactComponent('Can use a pragma comment', async ({ runtime }) => {
|
||||||
assert.ok(!result.error, `build error: ${result.error}`);
|
assert.ok(!result.error, `build error: ${result.error}`);
|
||||||
|
|
||||||
const $ = doc(result.contents);
|
const $ = doc(result.contents);
|
||||||
assert.equal($('#pragma-comment').length, 1, "rendered the PragmaComment component.");
|
assert.equal($('#pragma-comment').length, 1, 'rendered the PragmaComment component.');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
PreactComponent('Uses the new JSX transform', async ({ runtime }) => {
|
PreactComponent('Uses the new JSX transform', async ({ runtime }) => {
|
||||||
const result = await runtime.load('/pragma-comment');
|
const result = await runtime.load('/pragma-comment');
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ PreactComponent('Uses the new JSX transform', async ({ runtime }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = await runtime.load(componentUrl);
|
const component = await runtime.load(componentUrl);
|
||||||
const jsxRuntime = component.imports.filter(i => i.specifier.includes('jsx-runtime'));
|
const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
|
||||||
|
|
||||||
assert.ok(jsxRuntime, 'preact/jsx-runtime is used for the component');
|
assert.ok(jsxRuntime, 'preact/jsx-runtime is used for the component');
|
||||||
});
|
});
|
||||||
|
|
|
@ -86,9 +86,9 @@ React('uses the new JSX transform', async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = await runtime.load(componentUrl);
|
const component = await runtime.load(componentUrl);
|
||||||
const jsxRuntime = component.imports.filter(i => i.specifier.includes('jsx-runtime'));
|
const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
|
||||||
|
|
||||||
assert.ok(jsxRuntime, 'react/jsx-runtime is used for the component');
|
assert.ok(jsxRuntime, 'react/jsx-runtime is used for the component');
|
||||||
})
|
});
|
||||||
|
|
||||||
React.run();
|
React.run();
|
||||||
|
|
|
@ -5,11 +5,11 @@ export default {
|
||||||
knownEntrypoints: ['preact', 'preact/jsx-runtime', 'preact-render-to-string'],
|
knownEntrypoints: ['preact', 'preact/jsx-runtime', 'preact-render-to-string'],
|
||||||
jsxImportSource: 'preact',
|
jsxImportSource: 'preact',
|
||||||
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');
|
||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [jsx({}, { runtime: 'automatic', importSource: 'preact' })],
|
||||||
jsx({}, { runtime: 'automatic', importSource: 'preact' })
|
};
|
||||||
]
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,11 +5,11 @@ export default {
|
||||||
knownEntrypoints: ['react', 'react/jsx-runtime', 'react-dom', 'react-dom/server.js'],
|
knownEntrypoints: ['react', 'react/jsx-runtime', 'react-dom', 'react-dom/server.js'],
|
||||||
jsxImportSource: 'react',
|
jsxImportSource: 'react',
|
||||||
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');
|
||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [jsx({}, { runtime: 'automatic', importSource: 'react' })],
|
||||||
jsx({}, { runtime: 'automatic', importSource: 'react' })
|
};
|
||||||
]
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,9 +9,7 @@ export default (element) => (Component, props) => {
|
||||||
children: element.querySelector('astro-fragment'),
|
children: element.querySelector('astro-fragment'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const children = Array.isArray(component)
|
const children = Array.isArray(component) ? component : [component];
|
||||||
? component
|
|
||||||
: [ component ];
|
|
||||||
|
|
||||||
element.replaceChildren(...children);
|
element.replaceChildren(...children);
|
||||||
}
|
};
|
||||||
|
|
|
@ -8,10 +8,8 @@ export default {
|
||||||
jsxTransformOptions: async ({ isSSR }) => {
|
jsxTransformOptions: async ({ isSSR }) => {
|
||||||
const [{ default: solid }] = await Promise.all([import('babel-preset-solid')]);
|
const [{ default: solid }] = await Promise.all([import('babel-preset-solid')]);
|
||||||
const options = {
|
const options = {
|
||||||
presets: [
|
presets: [solid({}, { generate: isSSR ? 'ssr' : 'dom' })],
|
||||||
solid({}, { generate: isSSR ? 'ssr' : 'dom' }),
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSSR) {
|
if (isSSR) {
|
||||||
options.alias = {
|
options.alias = {
|
||||||
|
@ -21,5 +19,5 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,14 +9,15 @@ async function check(Component, props, children) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderToStaticMarkup(Component, props, children) {
|
async function renderToStaticMarkup(Component, props, children) {
|
||||||
const html = await renderToStringAsync(() => (
|
const html = await renderToStringAsync(
|
||||||
() => createComponent(Component, {
|
() => () =>
|
||||||
...props,
|
createComponent(Component, {
|
||||||
// In Solid SSR mode, `ssr` creates the expected structure for `children`.
|
...props,
|
||||||
// In Solid client mode, `ssr` is just a stub.
|
// In Solid SSR mode, `ssr` creates the expected structure for `children`.
|
||||||
children: ssr([`<astro-fragment>${children}</astro-fragment>`]),
|
// In Solid client mode, `ssr` is just a stub.
|
||||||
})
|
children: ssr([`<astro-fragment>${children}</astro-fragment>`]),
|
||||||
));
|
})
|
||||||
|
);
|
||||||
return { html };
|
return { html };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue