Skip to content

Commit

Permalink
Remove misleading warning when using a custom renderer (#12461)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people authored Dec 4, 2024
1 parent f56d349 commit 62939ad
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-knives-confess.md
Original file line number Diff line number Diff line change
@@ -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.
9 changes: 0 additions & 9 deletions packages/astro/src/runtime/server/render/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,6 @@ 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();
Expand Down
42 changes: 42 additions & 0 deletions packages/astro/test/custom-renderer.test.js
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions packages/astro/test/fixtures/custom-renderer/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions packages/astro/test/fixtures/custom-renderer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@test/custom-renderer",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
},
"scripts": {
"dev": "astro dev"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface Props {
msg: string;
}

export default function CustomRendererTest({ msg }: Props) {
return {
tag: "p",
text: msg
}
}
Original file line number Diff line number Diff line change
@@ -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 });
};
Original file line number Diff line number Diff line change
@@ -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());
},
},
};
}
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions packages/astro/test/fixtures/custom-renderer/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions packages/astro/test/fixtures/custom-renderer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@custom-renderer/*": ["src/custom-renderer/*"]
},
}
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 62939ad

Please sign in to comment.