mirror of
https://github.com/withastro/astro.git
synced 2025-01-13 22:11:20 -05:00
Remove misleading warning when using a custom renderer (#12461)
* fix: this message adds no value to developers; it checks against a static list of renderers while Astro allows to dynamically add custom renderers * feat: added framework-custom example to demonstrate the use of custom renderers with the log message fixed * chore: changeset added and package lock updated * chore: fix lint issue, but keeping arguments commented out for reference (real-world use) * chore: removed the example and updated the changeset accordingly * test: added fixture and test to prove the new behaviour * test: removing this specific test since it's only guarding if we ever revert this PR * Update test --------- Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> Co-authored-by: bluwy <bjornlu.dev@gmail.com>
This commit is contained in:
parent
f56d349ccc
commit
62939add0b
12 changed files with 218 additions and 9 deletions
5
.changeset/chatty-knives-confess.md
Normal file
5
.changeset/chatty-knives-confess.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Removes the misleading log message telling that a custom renderer is not recognized while it clearly is and works.
|
|
@ -260,15 +260,6 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (metadata.hydrate === 'only') {
|
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);
|
html = await renderSlotToString(result, slots?.fallback);
|
||||||
} else {
|
} else {
|
||||||
const componentRenderStartTime = performance.now();
|
const componentRenderStartTime = performance.now();
|
||||||
|
|
42
packages/astro/test/custom-renderer.test.js
Normal file
42
packages/astro/test/custom-renderer.test.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { after, before, describe, it } from 'node:test';
|
||||||
|
import * as cheerio from 'cheerio';
|
||||||
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
|
describe('Custom Renderer - SSR', () => {
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
root: './fixtures/custom-renderer/',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('dev', () => {
|
||||||
|
let devServer;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
devServer = await fixture.startDevServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await devServer.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders /', async () => {
|
||||||
|
const html = await fixture.fetch('/').then((res) => res.text());
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
assert.equal($('h1').text(), 'Client Directives');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders SSR custom renderer functional components as expected', async () => {
|
||||||
|
const res = await fixture.fetch('/');
|
||||||
|
assert.equal(res.status, 200);
|
||||||
|
|
||||||
|
const html = await res.text();
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
|
assert.equal($('p').length, 5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
9
packages/astro/test/fixtures/custom-renderer/astro.config.mjs
vendored
Normal file
9
packages/astro/test/fixtures/custom-renderer/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
// in a real-world scenario, this would be provided a separate package
|
||||||
|
import customRenderer from './src/custom-renderer';
|
||||||
|
|
||||||
|
// https://astro.build/config
|
||||||
|
export default defineConfig({
|
||||||
|
integrations: [customRenderer()]
|
||||||
|
});
|
11
packages/astro/test/fixtures/custom-renderer/package.json
vendored
Normal file
11
packages/astro/test/fixtures/custom-renderer/package.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "@test/custom-renderer",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"astro": "workspace:*"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev"
|
||||||
|
}
|
||||||
|
}
|
10
packages/astro/test/fixtures/custom-renderer/src/components/CustomRendererTest.ts
vendored
Normal file
10
packages/astro/test/fixtures/custom-renderer/src/components/CustomRendererTest.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
export interface Props {
|
||||||
|
msg: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CustomRendererTest({ msg }: Props) {
|
||||||
|
return {
|
||||||
|
tag: "p",
|
||||||
|
text: msg
|
||||||
|
}
|
||||||
|
}
|
25
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/client.ts
vendored
Normal file
25
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/client.ts
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
export default (parentElement: HTMLElement) =>
|
||||||
|
|
||||||
|
async (
|
||||||
|
Component: any,
|
||||||
|
props: Record<string, any>,
|
||||||
|
//{ default: children, ...slotted }: Record<string, any>,
|
||||||
|
//{ client }: Record<string, string>,
|
||||||
|
) => {
|
||||||
|
|
||||||
|
// in a real-world scenario, this would be a more complex function
|
||||||
|
// actually rendering the components return value (which might be an AST/VDOM)
|
||||||
|
|
||||||
|
const vdom = Component(props);
|
||||||
|
|
||||||
|
const node: Node = document.createElement(vdom.tag);
|
||||||
|
node.textContent = `${vdom.text} (rendered by client.ts)`;
|
||||||
|
parentElement.appendChild(node);
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
parentElement.addEventListener('astro:unmount', () => {
|
||||||
|
if (node.parentNode) {
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
}
|
||||||
|
}, { once: true });
|
||||||
|
};
|
23
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/index.ts
vendored
Normal file
23
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/index.ts
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import type { AstroIntegration, AstroRenderer, ContainerRenderer } from 'astro';
|
||||||
|
|
||||||
|
const getRenderer = (): AstroRenderer => ({
|
||||||
|
name: 'custom-renderer',
|
||||||
|
clientEntrypoint: '@custom-renderer/client',
|
||||||
|
serverEntrypoint: '@custom-renderer/server',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getContainerRenderer = (): ContainerRenderer => ({
|
||||||
|
name: 'custom-renderer',
|
||||||
|
serverEntrypoint: '@custom-renderer/server',
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function (): AstroIntegration {
|
||||||
|
return {
|
||||||
|
name: 'custom-renderer',
|
||||||
|
hooks: {
|
||||||
|
'astro:config:setup': ({ addRenderer }) => {
|
||||||
|
addRenderer(getRenderer());
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
42
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/server.ts
vendored
Normal file
42
packages/astro/test/fixtures/custom-renderer/src/custom-renderer/server.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import type { NamedSSRLoadedRendererValue, SSRResult } from 'astro';
|
||||||
|
|
||||||
|
type RendererContext = {
|
||||||
|
result: SSRResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function check(
|
||||||
|
this: RendererContext,
|
||||||
|
Component: any,
|
||||||
|
//props: Record<string, any>,
|
||||||
|
//children: any,
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (typeof Component !== 'function') return false;
|
||||||
|
|
||||||
|
// in a real-world scenario, this would be a more complex function
|
||||||
|
// that checks if the component should be rendered
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function renderToStaticMarkup(
|
||||||
|
this: RendererContext,
|
||||||
|
Component: any,
|
||||||
|
props: Record<string, any>,
|
||||||
|
//{ default: children, ...slotted }: Record<string, any>,
|
||||||
|
//metadata: AstroComponentMetadata | undefined,
|
||||||
|
) {
|
||||||
|
// in a real-world scenario, this would be a more complex function
|
||||||
|
// actually rendering the components return value (which might be an AST/VDOM)
|
||||||
|
// and render it as an HTML string
|
||||||
|
const vdom = Component(props);
|
||||||
|
return { attrs: {}, html: `<${vdom.tag}>${vdom.text} (rendered by server.ts)</${vdom.tag}>` };
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderer: NamedSSRLoadedRendererValue = {
|
||||||
|
name: 'custom-renderer',
|
||||||
|
check,
|
||||||
|
renderToStaticMarkup,
|
||||||
|
supportsAstroStaticSlot: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default renderer;
|
30
packages/astro/test/fixtures/custom-renderer/src/pages/index.astro
vendored
Normal file
30
packages/astro/test/fixtures/custom-renderer/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
import CustomRendererTest from '../components/CustomRendererTest';
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Custom Framework / Custom Renderer</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Client Directives</h1>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="client:only" client:only="custom-renderer" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="client:load" client:load />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="client:visible" client:visible />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="client:media" client:media="(max-width: 50em)" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="client:idle" client:idle />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<CustomRendererTest msg="none (SSR)" />
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
9
packages/astro/test/fixtures/custom-renderer/tsconfig.json
vendored
Normal file
9
packages/astro/test/fixtures/custom-renderer/tsconfig.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/base",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@custom-renderer/*": ["src/custom-renderer/*"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
|
@ -968,6 +968,12 @@ importers:
|
||||||
specifier: ^18.3.1
|
specifier: ^18.3.1
|
||||||
version: 18.3.1(react@18.3.1)
|
version: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
|
packages/astro/e2e/fixtures/custom-renderer:
|
||||||
|
dependencies:
|
||||||
|
astro:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../..
|
||||||
|
|
||||||
packages/astro/e2e/fixtures/dev-toolbar:
|
packages/astro/e2e/fixtures/dev-toolbar:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/preact':
|
'@astrojs/preact':
|
||||||
|
@ -2942,6 +2948,12 @@ importers:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../..
|
version: link:../../..
|
||||||
|
|
||||||
|
packages/astro/test/fixtures/custom-renderer:
|
||||||
|
dependencies:
|
||||||
|
astro:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../..
|
||||||
|
|
||||||
packages/astro/test/fixtures/data-collections:
|
packages/astro/test/fixtures/data-collections:
|
||||||
dependencies:
|
dependencies:
|
||||||
astro:
|
astro:
|
||||||
|
|
Loading…
Add table
Reference in a new issue