summaryrefslogtreecommitdiff
path: root/packages/integrations/solid/src/index.ts
blob: cfd38224cbbd706fdee6a6b703402b6d09f128f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import type { AstroConfig, AstroIntegration, AstroRenderer } from 'astro';
import { getSolidPkgsConfig } from './dependencies.js';

function getRenderer(): AstroRenderer {
	return {
		name: '@astrojs/solid-js',
		clientEntrypoint: '@astrojs/solid-js/client.js',
		serverEntrypoint: '@astrojs/solid-js/server.js',
		jsxImportSource: 'solid-js',
		jsxTransformOptions: async ({ ssr }) => {
			// @ts-expect-error types not found
			const [{ default: solid }] = await Promise.all([import('babel-preset-solid')]);
			const options = {
				presets: [solid({}, { generate: ssr ? 'ssr' : 'dom', hydratable: true })],
				plugins: [],
				// Otherwise, babel will try to consume the source map generated by esbuild
				// This causes unexpected issues with newline characters: https://github.com/withastro/astro/issues/3371
				// Note "vite-plugin-solid" does the same: https://github.com/solidjs/vite-plugin-solid/blob/master/src/index.ts#L344-L345
				inputSourceMap: false as any,
			};

			return options;
		},
	};
}

async function getViteConfiguration(isDev: boolean, astroConfig: AstroConfig) {
	// https://github.com/solidjs/vite-plugin-solid
	// We inject the dev mode only if the user explicitly wants it or if we are in dev (serve) mode
	const nestedDeps = ['solid-js', 'solid-js/web', 'solid-js/store', 'solid-js/html', 'solid-js/h'];
	const solidPkgsConfig = await getSolidPkgsConfig(!isDev, astroConfig);
	return {
		/**
		 * We only need esbuild on .ts or .js files.
		 * .tsx & .jsx files are handled by us
		 */
		esbuild: { include: /\.ts$/ },
		resolve: {
			conditions: ['solid', ...(isDev ? ['development'] : [])],
			dedupe: nestedDeps,
			alias: [{ find: /^solid-refresh$/, replacement: '/@solid-refresh' }],
		},
		optimizeDeps: {
			include: [...nestedDeps, ...solidPkgsConfig.optimizeDeps.include],
			exclude: ['@astrojs/solid-js/server.js', ...solidPkgsConfig.optimizeDeps.exclude],
		},
		ssr: {
			external: ['babel-preset-solid', ...solidPkgsConfig.ssr.external],
			noExternal: [...solidPkgsConfig.ssr.noExternal],
		},
	};
}

export default function (): AstroIntegration {
	return {
		name: '@astrojs/solid-js',
		hooks: {
			'astro:config:setup': async ({ command, addRenderer, updateConfig, config }) => {
				addRenderer(getRenderer());
				updateConfig({ vite: await getViteConfiguration(command === 'dev', config) });
			},
		},
	};
}