mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Support React 19 (#10942)
* Support React 19 * Fix lint * Update .changeset/short-phones-breathe.md * fix: update types peer dep --------- Co-authored-by: bholmesdev <hey@bholmes.dev>
This commit is contained in:
parent
4b693c0476
commit
d47baa466a
3 changed files with 57 additions and 23 deletions
5
.changeset/short-phones-breathe.md
Normal file
5
.changeset/short-phones-breathe.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@astrojs/react": patch
|
||||
---
|
||||
|
||||
Updates package to support React 19 beta
|
|
@ -60,10 +60,10 @@
|
|||
"vite": "^5.2.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.50 || ^18.0.21",
|
||||
"@types/react-dom": "^17.0.17 || ^18.0.6",
|
||||
"react": "^17.0.2 || ^18.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0"
|
||||
"@types/react": "^17.0.50 || ^18.0.21 || npm:types-react@beta",
|
||||
"@types/react-dom": "^17.0.17 || ^18.0.6 || npm:types-react-dom@beta",
|
||||
"react": "^17.0.2 || ^18.0.0 || ^19.0.0-beta",
|
||||
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0-beta"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"
|
||||
|
|
|
@ -12,15 +12,44 @@ export type ReactIntegrationOptions = Pick<
|
|||
|
||||
const FAST_REFRESH_PREAMBLE = react.preambleCode;
|
||||
|
||||
function getRenderer() {
|
||||
const versionsConfig = {
|
||||
17: {
|
||||
server: '@astrojs/react/server-v17.js',
|
||||
client: '@astrojs/react/client-v17.js',
|
||||
externals: ['react-dom/server.js', 'react-dom/client.js'],
|
||||
},
|
||||
18: {
|
||||
server: '@astrojs/react/server.js',
|
||||
client: '@astrojs/react/client.js',
|
||||
externals: ['react-dom/server', 'react-dom/client']
|
||||
},
|
||||
19: {
|
||||
server: '@astrojs/react/server.js',
|
||||
client: '@astrojs/react/client.js',
|
||||
externals: ['react-dom/server', 'react-dom/client']
|
||||
}
|
||||
};
|
||||
|
||||
type SupportedReactVersion = keyof (typeof versionsConfig);
|
||||
type ReactVersionConfig = (typeof versionsConfig)[SupportedReactVersion];
|
||||
|
||||
function getReactMajorVersion(): number {
|
||||
const matches = /\d+\./.exec(ReactVersion);
|
||||
if(!matches) {
|
||||
return NaN;
|
||||
}
|
||||
return Number(matches[0]);
|
||||
}
|
||||
|
||||
function isUnsupportedVersion(majorVersion: number) {
|
||||
return majorVersion < 17 || majorVersion > 19 || Number.isNaN(majorVersion);
|
||||
}
|
||||
|
||||
function getRenderer(reactConfig: ReactVersionConfig) {
|
||||
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',
|
||||
clientEntrypoint: reactConfig.client,
|
||||
serverEntrypoint: reactConfig.server,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -51,22 +80,18 @@ function getViteConfiguration({
|
|||
exclude,
|
||||
babel,
|
||||
experimentalReactChildren,
|
||||
}: ReactIntegrationOptions = {}) {
|
||||
}: ReactIntegrationOptions = {}, reactConfig: ReactVersionConfig) {
|
||||
return {
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
ReactVersion.startsWith('18.')
|
||||
? '@astrojs/react/client.js'
|
||||
: '@astrojs/react/client-v17.js',
|
||||
reactConfig.client,
|
||||
'react',
|
||||
'react/jsx-runtime',
|
||||
'react/jsx-dev-runtime',
|
||||
'react-dom',
|
||||
],
|
||||
exclude: [
|
||||
ReactVersion.startsWith('18.')
|
||||
? '@astrojs/react/server.js'
|
||||
: '@astrojs/react/server-v17.js',
|
||||
reactConfig.server,
|
||||
],
|
||||
},
|
||||
plugins: [react({ include, exclude, babel }), optionsPlugin(!!experimentalReactChildren)],
|
||||
|
@ -74,9 +99,7 @@ function getViteConfiguration({
|
|||
dedupe: ['react', 'react-dom', 'react-dom/server'],
|
||||
},
|
||||
ssr: {
|
||||
external: ReactVersion.startsWith('18.')
|
||||
? ['react-dom/server', 'react-dom/client']
|
||||
: ['react-dom/server.js', 'react-dom/client.js'],
|
||||
external: reactConfig.externals,
|
||||
noExternal: [
|
||||
// These are all needed to get mui to work.
|
||||
'@mui/material',
|
||||
|
@ -95,13 +118,19 @@ export default function ({
|
|||
babel,
|
||||
experimentalReactChildren,
|
||||
}: ReactIntegrationOptions = {}): AstroIntegration {
|
||||
const majorVersion = getReactMajorVersion();
|
||||
if(isUnsupportedVersion(majorVersion)) {
|
||||
throw new Error(`Unsupported React version: ${majorVersion}.`);
|
||||
}
|
||||
const versionConfig = versionsConfig[majorVersion as SupportedReactVersion];
|
||||
|
||||
return {
|
||||
name: '@astrojs/react',
|
||||
hooks: {
|
||||
'astro:config:setup': ({ command, addRenderer, updateConfig, injectScript }) => {
|
||||
addRenderer(getRenderer());
|
||||
addRenderer(getRenderer(versionConfig));
|
||||
updateConfig({
|
||||
vite: getViteConfiguration({ include, exclude, babel, experimentalReactChildren }),
|
||||
vite: getViteConfiguration({ include, exclude, babel, experimentalReactChildren }, versionConfig),
|
||||
});
|
||||
if (command === 'dev') {
|
||||
const preamble = FAST_REFRESH_PREAMBLE.replace(`__BASE__`, '/');
|
||||
|
|
Loading…
Reference in a new issue