mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
improves client:only
error message (#10470)
* improves `client:only` error message * add changeset * Fix condition for rendering component * Update rendererAliases in component.ts * Update changeset
This commit is contained in:
parent
16d3f1897a
commit
320c309ca9
2 changed files with 52 additions and 15 deletions
5
.changeset/calm-hotels-kiss.md
Normal file
5
.changeset/calm-hotels-kiss.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"astro": patch
|
||||
---
|
||||
|
||||
improves `client:only` error message
|
|
@ -32,6 +32,7 @@ import { formatList, internalSpreadAttributes, renderElement, voidElementNames }
|
|||
|
||||
const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering');
|
||||
const rendererAliases = new Map([['solid', 'solid-js']]);
|
||||
const clientOnlyValues = new Set(['solid-js', 'react', 'preact', 'vue', 'svelte', 'lit']);
|
||||
|
||||
function guessRenderers(componentUrl?: string): string[] {
|
||||
const extname = componentUrl?.split('.').pop();
|
||||
|
@ -80,7 +81,7 @@ async function renderFrameworkComponent(
|
|||
_props: Record<string | number, any>,
|
||||
slots: any = {}
|
||||
): Promise<RenderInstance> {
|
||||
if (!Component && !_props['client:only']) {
|
||||
if (!Component && "client:only" in _props === false) {
|
||||
throw new Error(
|
||||
`Unable to render ${displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?`
|
||||
);
|
||||
|
@ -164,13 +165,14 @@ async function renderFrameworkComponent(
|
|||
} else {
|
||||
// Attempt: use explicitly passed renderer name
|
||||
if (metadata.hydrateArgs) {
|
||||
const passedName = metadata.hydrateArgs;
|
||||
const rendererName = rendererAliases.has(passedName)
|
||||
? rendererAliases.get(passedName)
|
||||
: passedName;
|
||||
renderer = renderers.find(
|
||||
({ name }) => name === `@astrojs/${rendererName}` || name === rendererName
|
||||
);
|
||||
const rendererName = rendererAliases.has(metadata.hydrateArgs)
|
||||
? rendererAliases.get(metadata.hydrateArgs)
|
||||
: metadata.hydrateArgs;
|
||||
if (clientOnlyValues.has(rendererName)) {
|
||||
renderer = renderers.find(
|
||||
({ name }) => name === `@astrojs/${rendererName}` || name === rendererName
|
||||
);
|
||||
}
|
||||
}
|
||||
// Attempt: user only has a single renderer, default to that
|
||||
if (!renderer && validRenderers.length === 1) {
|
||||
|
@ -189,13 +191,34 @@ async function renderFrameworkComponent(
|
|||
// If no one claimed the renderer
|
||||
if (!renderer) {
|
||||
if (metadata.hydrate === 'only') {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.NoClientOnlyHint,
|
||||
message: AstroErrorData.NoClientOnlyHint.message(metadata.displayName),
|
||||
hint: AstroErrorData.NoClientOnlyHint.hint(
|
||||
probableRendererNames.map((r) => r.replace('@astrojs/', '')).join('|')
|
||||
),
|
||||
});
|
||||
const rendererName = rendererAliases.has(metadata.hydrateArgs)
|
||||
? rendererAliases.get(metadata.hydrateArgs)
|
||||
: metadata.hydrateArgs;
|
||||
if (clientOnlyValues.has(rendererName)) {
|
||||
// throw an error if provide correct client:only directive but not find the renderer
|
||||
const plural = validRenderers.length > 1;
|
||||
throw new AstroError({
|
||||
...AstroErrorData.NoMatchingRenderer,
|
||||
message: AstroErrorData.NoMatchingRenderer.message(
|
||||
metadata.displayName,
|
||||
metadata?.componentUrl?.split('.').pop(),
|
||||
plural,
|
||||
validRenderers.length
|
||||
),
|
||||
hint: AstroErrorData.NoMatchingRenderer.hint(
|
||||
formatList(probableRendererNames.map((r) => '`' + r + '`'))
|
||||
),
|
||||
});
|
||||
} else {
|
||||
// throw an error if an invalid hydration directive was provided
|
||||
throw new AstroError({
|
||||
...AstroErrorData.NoClientOnlyHint,
|
||||
message: AstroErrorData.NoClientOnlyHint.message(metadata.displayName),
|
||||
hint: AstroErrorData.NoClientOnlyHint.hint(
|
||||
probableRendererNames.map((r) => r.replace('@astrojs/', '')).join('|')
|
||||
),
|
||||
});
|
||||
}
|
||||
} else if (typeof Component !== 'string') {
|
||||
const matchingRenderers = validRenderers.filter((r) =>
|
||||
probableRendererNames.includes(r.name)
|
||||
|
@ -241,6 +264,15 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
|
|||
}
|
||||
} else {
|
||||
if (metadata.hydrate === 'only') {
|
||||
const rendererName = rendererAliases.has(metadata.hydrateArgs)
|
||||
? rendererAliases.get(metadata.hydrateArgs)
|
||||
: metadata.hydrateArgs;
|
||||
if (!clientOnlyValues.has(rendererName)) {
|
||||
// warning if provide incorrect client:only directive but find the renderer by guess
|
||||
console.warn(
|
||||
`The client:only directive for ${metadata.displayName} is not recognized. The renderer ${renderer.name} will be used. If you intended to use a different renderer, please provide a valid client:only directive.`
|
||||
);
|
||||
}
|
||||
html = await renderSlotToString(result, slots?.fallback);
|
||||
} else {
|
||||
const componentRenderStartTime = performance.now();
|
||||
|
|
Loading…
Reference in a new issue