0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-10 22:38:53 -05:00
astro/packages/integrations/solid/src/index.ts
2024-11-27 18:00:35 +08:00

112 lines
2.7 KiB
TypeScript

import type {
AstroIntegration,
AstroIntegrationLogger,
AstroRenderer,
ContainerRenderer,
} from 'astro';
import type { PluginOption, UserConfig } from 'vite';
import solid, { type Options as ViteSolidPluginOptions } from 'vite-plugin-solid';
// TODO: keep in sync with https://github.com/thetarnav/solid-devtools/blob/main/packages/main/src/vite/index.ts#L7
type DevtoolsPluginOptions = {
/** Add automatic name when creating signals, memos, stores, or mutables */
autoname?: boolean;
locator?:
| boolean
| {
/** Choose in which IDE the component source code should be revealed. */
targetIDE?: string;
/**
* Holding which key should enable the locator overlay?
* @default 'Alt'
*/
key?: string;
/** Inject location attributes to jsx templates */
jsxLocation?: boolean;
/** Inject location information to component declarations */
componentLocation?: boolean;
};
};
type DevtoolsPlugin = (_options?: DevtoolsPluginOptions) => PluginOption;
async function getDevtoolsPlugin(logger: AstroIntegrationLogger, retrieve: boolean) {
if (!retrieve) {
return null;
}
try {
// @ts-ignore
return (await import('solid-devtools/vite')).default as DevtoolsPlugin;
} catch (_) {
logger.warn(
'Solid Devtools requires `solid-devtools` as a peer dependency, add it to your project.',
);
return null;
}
}
function getViteConfiguration(
{ include, exclude }: Options,
devtoolsPlugin: DevtoolsPlugin | null,
) {
const config: UserConfig = {
optimizeDeps: {
exclude: ['@astrojs/solid-js/server.js'],
},
plugins: [solid({ include, exclude, ssr: true })],
};
if (devtoolsPlugin) {
config.plugins?.push(devtoolsPlugin({ autoname: true }));
}
return config;
}
function getRenderer(): AstroRenderer {
return {
name: '@astrojs/solid-js',
clientEntrypoint: '@astrojs/solid-js/client.js',
serverEntrypoint: '@astrojs/solid-js/server.js',
};
}
export function getContainerRenderer(): ContainerRenderer {
return {
name: '@astrojs/solid',
serverEntrypoint: '@astrojs/solid-js/server.js',
};
}
export interface Options extends Pick<ViteSolidPluginOptions, 'include' | 'exclude'> {
devtools?: boolean;
}
export default function (options: Options = {}): AstroIntegration {
return {
name: '@astrojs/solid-js',
hooks: {
'astro:config:setup': async ({
command,
addRenderer,
updateConfig,
injectScript,
logger,
}) => {
const devtoolsPlugin = await getDevtoolsPlugin(
logger,
!!options.devtools && command === 'dev',
);
addRenderer(getRenderer());
updateConfig({
vite: getViteConfiguration(options, devtoolsPlugin),
});
if (devtoolsPlugin) {
injectScript('page', 'import "solid-devtools";');
}
},
},
};
}