mirror of
https://github.com/withastro/astro.git
synced 2025-12-05 18:56:38 -06:00
feat: return clientEntrypoint from getContainerRenderer (#14715)
* feat: return `clientEntrypoint` from `getContainerRenderer`
* ✂️
This commit is contained in:
15
.changeset/fresh-hairs-battle.md
Normal file
15
.changeset/fresh-hairs-battle.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'@astrojs/preact': patch
|
||||
'@astrojs/svelte': patch
|
||||
'@astrojs/react': patch
|
||||
'@astrojs/solid-js': patch
|
||||
'@astrojs/mdx': patch
|
||||
'@astrojs/vue': patch
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Adds support for client hydration in `getContainerRenderer()`
|
||||
|
||||
The `getContainerRenderer()` function is exported by Astro framework integrations to simplify the process of rendering framework components when using the experimental Container API inside a Vite or Vitest environment. This update adds the client hydration entrypoint to the returned object, enabling client-side interactivity for components rendered using this function. Previously this required users to manually call `container.addClientRenderer()` with the appropriate client renderer entrypoint.
|
||||
|
||||
See [the `container-with-vitest` demo](https://github.com/withastro/astro/blob/main/examples/container-with-vitest/test/ReactWrapper.test.ts) for a usage example, and [the Container API documentation](https://docs.astro.build/en/reference/container-reference/#renderers-option) for more information on using framework components with the experimental Container API.
|
||||
@@ -2,4 +2,4 @@
|
||||
import Counter from './Counter.jsx';
|
||||
---
|
||||
|
||||
<Counter initialCount={5} />
|
||||
<Counter initialCount={5} client:load />
|
||||
|
||||
@@ -14,4 +14,7 @@ test('ReactWrapper with react renderer', async () => {
|
||||
|
||||
expect(result).toContain('Counter');
|
||||
expect(result).toContain('Count: <!-- -->5');
|
||||
expect(result, 'Includes client hydration reference').toContain(
|
||||
'renderer-url="@astrojs/react/client.js"',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -28,7 +28,10 @@ import type {
|
||||
} from '../types/public/internal.js';
|
||||
import { ContainerPipeline } from './pipeline.js';
|
||||
|
||||
/** Public type, used for integrations to define a renderer for the container API */
|
||||
/**
|
||||
* Public type, used for integrations to define a renderer for the container API
|
||||
* @deprecated Use `AstroRenderer` instead.
|
||||
*/
|
||||
export type ContainerRenderer = {
|
||||
/**
|
||||
* The name of the renderer.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AstroIntegration, AstroRenderer, ContainerRenderer } from 'astro';
|
||||
import type { AstroIntegration, AstroRenderer } from 'astro';
|
||||
|
||||
const getRenderer = (): AstroRenderer => ({
|
||||
name: 'custom-renderer',
|
||||
@@ -6,10 +6,7 @@ const getRenderer = (): AstroRenderer => ({
|
||||
serverEntrypoint: '@custom-renderer/server',
|
||||
})
|
||||
|
||||
export const getContainerRenderer = (): ContainerRenderer => ({
|
||||
name: 'custom-renderer',
|
||||
serverEntrypoint: '@custom-renderer/server',
|
||||
})
|
||||
export { getRenderer as getContainerRenderer };
|
||||
|
||||
export default function (): AstroIntegration {
|
||||
return {
|
||||
@@ -20,4 +17,4 @@ export default function (): AstroIntegration {
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { markdownConfigDefaults } from '@astrojs/markdown-remark';
|
||||
import type {
|
||||
AstroIntegration,
|
||||
AstroIntegrationLogger,
|
||||
ContainerRenderer,
|
||||
AstroRenderer,
|
||||
ContentEntryType,
|
||||
HookParameters,
|
||||
} from 'astro';
|
||||
@@ -33,7 +33,7 @@ type SetupHookParams = HookParameters<'astro:config:setup'> & {
|
||||
addContentEntryType: (contentEntryType: ContentEntryType) => void;
|
||||
};
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
export function getContainerRenderer(): AstroRenderer {
|
||||
return {
|
||||
name: 'astro:jsx',
|
||||
serverEntrypoint: '@astrojs/mdx/server.js',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { preact, type PreactPluginOptions as VitePreactPluginOptions } from '@preact/preset-vite';
|
||||
import type { AstroIntegration, AstroRenderer, ContainerRenderer, ViteUserConfig } from 'astro';
|
||||
import type { AstroIntegration, AstroRenderer, ViteUserConfig } from 'astro';
|
||||
|
||||
const babelCwd = new URL('../', import.meta.url);
|
||||
|
||||
@@ -12,12 +12,7 @@ function getRenderer(development: boolean): AstroRenderer {
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
return {
|
||||
name: '@astrojs/preact',
|
||||
serverEntrypoint: '@astrojs/preact/server.js',
|
||||
};
|
||||
}
|
||||
export const getContainerRenderer = (): AstroRenderer => getRenderer(false);
|
||||
|
||||
export interface Options extends Pick<VitePreactPluginOptions, 'include' | 'exclude'> {
|
||||
compat?: boolean;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import react, { type Options as ViteReactPluginOptions } from '@vitejs/plugin-react';
|
||||
import type { AstroIntegration, ContainerRenderer } from 'astro';
|
||||
import type { AstroIntegration, AstroRenderer } from 'astro';
|
||||
import type * as vite from 'vite';
|
||||
import {
|
||||
getReactMajorVersion,
|
||||
isUnsupportedVersion,
|
||||
isSupportedReactVersion,
|
||||
type ReactVersionConfig,
|
||||
type SupportedReactVersion,
|
||||
versionsConfig,
|
||||
} from './version.js';
|
||||
|
||||
@@ -102,10 +101,10 @@ export default function ({
|
||||
experimentalDisableStreaming,
|
||||
}: ReactIntegrationOptions = {}): AstroIntegration {
|
||||
const majorVersion = getReactMajorVersion();
|
||||
if (isUnsupportedVersion(majorVersion)) {
|
||||
if (!isSupportedReactVersion(majorVersion)) {
|
||||
throw new Error(`Unsupported React version: ${majorVersion}.`);
|
||||
}
|
||||
const versionConfig = versionsConfig[majorVersion as SupportedReactVersion];
|
||||
const versionConfig = versionsConfig[majorVersion];
|
||||
|
||||
return {
|
||||
name: '@astrojs/react',
|
||||
@@ -139,15 +138,10 @@ export default function ({
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
export function getContainerRenderer(): AstroRenderer {
|
||||
const majorVersion = getReactMajorVersion();
|
||||
if (isUnsupportedVersion(majorVersion)) {
|
||||
if (!isSupportedReactVersion(majorVersion)) {
|
||||
throw new Error(`Unsupported React version: ${majorVersion}.`);
|
||||
}
|
||||
const versionConfig = versionsConfig[majorVersion as SupportedReactVersion];
|
||||
|
||||
return {
|
||||
name: '@astrojs/react',
|
||||
serverEntrypoint: versionConfig.server,
|
||||
};
|
||||
return getRenderer(versionsConfig[majorVersion]);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { version as ReactVersion } from 'react-dom';
|
||||
|
||||
export type SupportedReactVersion = keyof typeof versionsConfig;
|
||||
type SupportedReactVersion = keyof typeof versionsConfig;
|
||||
export type ReactVersionConfig = (typeof versionsConfig)[SupportedReactVersion];
|
||||
|
||||
export function getReactMajorVersion(): number {
|
||||
@@ -11,8 +11,10 @@ export function getReactMajorVersion(): number {
|
||||
return Number(matches[0]);
|
||||
}
|
||||
|
||||
export function isUnsupportedVersion(majorVersion: number) {
|
||||
return majorVersion < 17 || majorVersion > 19 || Number.isNaN(majorVersion);
|
||||
export function isSupportedReactVersion(
|
||||
majorVersion: number,
|
||||
): majorVersion is SupportedReactVersion {
|
||||
return majorVersion in versionsConfig;
|
||||
}
|
||||
|
||||
export const versionsConfig = {
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import type {
|
||||
AstroIntegration,
|
||||
AstroIntegrationLogger,
|
||||
AstroRenderer,
|
||||
ContainerRenderer,
|
||||
} from 'astro';
|
||||
import type { AstroIntegration, AstroIntegrationLogger, AstroRenderer } from 'astro';
|
||||
import type { PluginOption, UserConfig } from 'vite';
|
||||
import solid, { type Options as ViteSolidPluginOptions } from 'vite-plugin-solid';
|
||||
|
||||
@@ -72,12 +67,7 @@ function getRenderer(): AstroRenderer {
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
return {
|
||||
name: '@astrojs/solid',
|
||||
serverEntrypoint: '@astrojs/solid-js/server.js',
|
||||
};
|
||||
}
|
||||
export { getRenderer as getContainerRenderer };
|
||||
|
||||
export interface Options extends Pick<ViteSolidPluginOptions, 'include' | 'exclude'> {
|
||||
devtools?: boolean;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Options } from '@sveltejs/vite-plugin-svelte';
|
||||
import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import type { AstroIntegration, AstroRenderer, ContainerRenderer } from 'astro';
|
||||
import type { AstroIntegration, AstroRenderer } from 'astro';
|
||||
|
||||
function getRenderer(): AstroRenderer {
|
||||
return {
|
||||
@@ -10,12 +10,7 @@ function getRenderer(): AstroRenderer {
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
return {
|
||||
name: '@astrojs/svelte',
|
||||
serverEntrypoint: '@astrojs/svelte/server.js',
|
||||
};
|
||||
}
|
||||
export { getRenderer as getContainerRenderer };
|
||||
|
||||
export default function svelteIntegration(options?: Options): AstroIntegration {
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Options as VueOptions } from '@vitejs/plugin-vue';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx';
|
||||
import { MagicString } from '@vue/compiler-sfc';
|
||||
import type { AstroIntegration, AstroRenderer, ContainerRenderer, HookParameters } from 'astro';
|
||||
import type { AstroIntegration, AstroRenderer, HookParameters } from 'astro';
|
||||
import type { Plugin, UserConfig } from 'vite';
|
||||
import type { VitePluginVueDevToolsOptions } from 'vite-plugin-vue-devtools';
|
||||
|
||||
@@ -32,12 +32,7 @@ function getJsxRenderer(): AstroRenderer {
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRenderer(): ContainerRenderer {
|
||||
return {
|
||||
name: '@astrojs/vue',
|
||||
serverEntrypoint: '@astrojs/vue/server.js',
|
||||
};
|
||||
}
|
||||
export { getRenderer as getContainerRenderer };
|
||||
|
||||
function virtualAppEntrypoint(options?: Options): Plugin {
|
||||
let isBuild: boolean;
|
||||
|
||||
Reference in New Issue
Block a user