summaryrefslogtreecommitdiff
path: root/packages/integrations/react/src/index.ts
blob: 5560622823b0d64d013eeb0d526036632ab5d1f5 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import type { AstroIntegration } from 'astro';
import { version as ReactVersion } from 'react-dom';
import type * as vite from 'vite';

function getRenderer() {
	return {
		name: '@astrojs/react',
		clientEntrypoint: ReactVersion.startsWith('18.')
			? '@astrojs/react/client.js'
			: '@astrojs/react/client-v17.js',
		serverEntrypoint: ReactVersion.startsWith('18.')
			? '@astrojs/react/server.js'
			: '@astrojs/react/server-v17.js',
		jsxImportSource: 'react',
		jsxTransformOptions: async () => {
			// @ts-expect-error types not found
			const babelPluginTransformReactJsxModule = await import('@babel/plugin-transform-react-jsx');
			const jsx =
				babelPluginTransformReactJsxModule?.default?.default ??
				babelPluginTransformReactJsxModule?.default;
			return {
				plugins: [
					jsx(
						{},
						{
							runtime: 'automatic',
							// This option tells the JSX transform how to construct the "*/jsx-runtime" import.
							// In React v17, we had to shim this due to an export map issue in React.
							// In React v18, this issue was fixed and we can import "react/jsx-runtime" directly.
							// See `./jsx-runtime.js` for more details.
							importSource: ReactVersion.startsWith('18.') ? 'react' : '@astrojs/react',
						}
					),
				],
			};
		},
	};
}

function optionsPlugin(experimentalReactChildren: boolean): vite.Plugin {
	const virtualModule = 'astro:react:opts';
	const virtualModuleId = '\0' + virtualModule; 
	return 			{
		name: '@astrojs/react:opts',
		resolveId(id) {
			if(id === virtualModule) {
				return virtualModuleId;
			}
		},
		load(id) {
			if(id === virtualModuleId) {
				return {
					code: `export default {
						experimentalReactChildren: ${JSON.stringify(experimentalReactChildren)}
					}`
				};
			}
		}
	};
}

function getViteConfiguration(experimentalReactChildren: boolean) {
	return {
		optimizeDeps: {
			include: [
				ReactVersion.startsWith('18.')
					? '@astrojs/react/client.js'
					: '@astrojs/react/client-v17.js',
				'react',
				'react/jsx-runtime',
				'react/jsx-dev-runtime',
				'react-dom',
			],
			exclude: [
				ReactVersion.startsWith('18.')
					? '@astrojs/react/server.js'
					: '@astrojs/react/server-v17.js',
			],
		},
		resolve: {
			dedupe: ['react', 'react-dom'],
		},
		ssr: {
			external: ReactVersion.startsWith('18.')
				? ['react-dom/server', 'react-dom/client']
				: ['react-dom/server.js', 'react-dom/client.js'],
			noExternal: [
				// These are all needed to get mui to work.
				'@mui/material',
				'@mui/base',
				'@babel/runtime',
				'redoc',
				'use-immer',
			],
		},
		plugins: [
			optionsPlugin(experimentalReactChildren)
		]
	};
}

export type ReactIntegrationOptions = {
	experimentalReactChildren: boolean;
}

export default function ({ experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false }): AstroIntegration {
	return {
		name: '@astrojs/react',
		hooks: {
			'astro:config:setup': ({ addRenderer, updateConfig }) => {
				addRenderer(getRenderer());
				updateConfig({ vite: getViteConfiguration(experimentalReactChildren) });
			},
		},
	};
}
2025-03-21Repair server islands to work with client router (#13481)Gravatar Martin Trapp 2-6/+11 2025-03-21fix: generate correct external redirects (#13480)Gravatar Matt Kane 3-4/+21 2025-03-21fix(deps): update all non-major dependencies (#13440)Gravatar renovate[bot] 24-435/+436 2025-03-21[ci] formatGravatar Florian Lefebvre 2-2/+2 2025-03-21feat(cloudflare): global env (#13444)Gravatar Florian Lefebvre 6-47/+130 2025-03-21fix(deps): update astro client runtimes (#13474)Gravatar renovate[bot] 7-345/+348 2025-03-20Small change to linking style (#13472)Gravatar Chris Swithinbank 1-1/+1 2025-03-20Add deprecation notice to Tailwind integration README (#13471)Gravatar Chris Swithinbank 2-6/+11 2025-03-20[ci] formatGravatar Matt Kane 2-2/+1 2025-03-20fix(preact,svelte): empty target container before rendering `client:only` isl...Gravatar Matt Kane 5-5/+41 2025-03-20chore(renovate): group updates (#13466)Gravatar Emanuele Stoppa 1-11/+58 2025-03-19[ci] formatGravatar Matt Kane 1-3/+2 2025-03-19fix: don't attempt to move files after build with base (#13463)Gravatar Matt Kane 8-13/+66 2025-03-19[ci] formatGravatar Emanuele Stoppa 2-6/+18 2025-03-19fix(routing): don't add site to static redirects (#13447)Gravatar Emanuele Stoppa 7-10/+49 2025-03-18[ci] formatGravatar Matt Kane 2-2/+1 2025-03-18fix: set correct statusText for custom error pages (#13457)Gravatar Matt Kane 4-2/+19 2025-03-18chore(deps): update github-actions (#13459)Gravatar renovate[bot] 9-13/+13 2025-03-18chore(deps): update github-actions (#13458)Gravatar renovate[bot] 1-5/+5 2025-03-18[ci] formatGravatar Emanuele Stoppa 1-1/+3 2025-03-18chore: remove deprecated package (#13455)Gravatar Emanuele Stoppa 3-23/+16 2025-03-18fix(deps): update dependency miniflare to v4 (#13441)Gravatar renovate[bot] 2-31/+31