Skip to content

Commit

Permalink
Support React 19 (#10942)
Browse files Browse the repository at this point in the history
* Support React 19

* Fix lint

* Update .changeset/short-phones-breathe.md

* fix: update types peer dep

---------

Co-authored-by: bholmesdev <hey@bholmes.dev>
  • Loading branch information
matthewp and bholmesdev committed May 7, 2024
1 parent 4b693c0 commit d47baa4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-phones-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/react": patch
---

Updates package to support React 19 beta
8 changes: 4 additions & 4 deletions packages/integrations/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
67 changes: 48 additions & 19 deletions packages/integrations/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}

Expand Down Expand Up @@ -51,32 +80,26 @@ 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)],
resolve: {
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',
Expand All @@ -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__`, '/');
Expand Down

0 comments on commit d47baa4

Please sign in to comment.