diff options
author | 2025-06-05 14:25:23 +0000 | |
---|---|---|
committer | 2025-06-05 14:25:23 +0000 | |
commit | e586d7d704d475afe3373a1de6ae20d504f79d6d (patch) | |
tree | 7e3fa24807cebd48a86bd40f866d792181191ee9 /packages/integrations/preact/src/index.ts | |
download | astro-latest.tar.gz astro-latest.tar.zst astro-latest.zip |
Sync from a8e1c0a7402940e0fc5beef669522b315052df1blatest
Diffstat (limited to 'packages/integrations/preact/src/index.ts')
-rw-r--r-- | packages/integrations/preact/src/index.ts | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/packages/integrations/preact/src/index.ts b/packages/integrations/preact/src/index.ts new file mode 100644 index 000000000..fd16a9e4a --- /dev/null +++ b/packages/integrations/preact/src/index.ts @@ -0,0 +1,88 @@ +import { fileURLToPath } from 'node:url'; +import { type PreactPluginOptions as VitePreactPluginOptions, preact } from '@preact/preset-vite'; +import type { AstroIntegration, AstroRenderer, ContainerRenderer, ViteUserConfig } from 'astro'; + +const babelCwd = new URL('../', import.meta.url); + +function getRenderer(development: boolean): AstroRenderer { + return { + name: '@astrojs/preact', + clientEntrypoint: development ? '@astrojs/preact/client-dev.js' : '@astrojs/preact/client.js', + serverEntrypoint: '@astrojs/preact/server.js', + }; +} + +export function getContainerRenderer(): ContainerRenderer { + return { + name: '@astrojs/preact', + serverEntrypoint: '@astrojs/preact/server.js', + }; +} + +export interface Options extends Pick<VitePreactPluginOptions, 'include' | 'exclude'> { + compat?: boolean; + devtools?: boolean; +} + +export default function ({ include, exclude, compat, devtools }: Options = {}): AstroIntegration { + return { + name: '@astrojs/preact', + hooks: { + 'astro:config:setup': ({ addRenderer, updateConfig, command, injectScript }) => { + const preactPlugin = preact({ + reactAliasesEnabled: compat ?? false, + include, + exclude, + babel: { + cwd: fileURLToPath(babelCwd), + }, + }); + + const viteConfig: ViteUserConfig = { + optimizeDeps: { + include: ['@astrojs/preact/client.js', 'preact', 'preact/jsx-runtime'], + exclude: ['@astrojs/preact/server.js'], + }, + }; + + if (compat) { + viteConfig.optimizeDeps!.include!.push( + 'preact/compat', + 'preact/test-utils', + 'preact/compat/jsx-runtime', + ); + viteConfig.resolve = { + dedupe: ['preact/compat', 'preact'], + }; + // noExternal React entrypoints to be bundled, resolved, and aliased by Vite + viteConfig.ssr = { + noExternal: ['react', 'react-dom', 'react-dom/test-utils', 'react/jsx-runtime'], + }; + } + + viteConfig.plugins = [preactPlugin]; + + addRenderer(getRenderer(command === 'dev')); + updateConfig({ + vite: viteConfig, + }); + + if (command === 'dev' && devtools) { + injectScript('page', 'import "preact/debug";'); + } + }, + 'astro:config:done': ({ logger, config }) => { + const knownJsxRenderers = ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js']; + const enabledKnownJsxRenderers = config.integrations.filter((renderer) => + knownJsxRenderers.includes(renderer.name), + ); + + if (enabledKnownJsxRenderers.length > 1 && !include && !exclude) { + logger.warn( + 'More than one JSX renderer is enabled. This will lead to unexpected behavior unless you set the `include` or `exclude` option. See https://docs.astro.build/en/guides/integrations-guide/preact/#combining-multiple-jsx-frameworks for more information.', + ); + } + }, + }, + }; +} |