diff options
Diffstat (limited to 'packages/integrations/react')
-rw-r--r-- | packages/integrations/react/package.json | 8 | ||||
-rw-r--r-- | packages/integrations/react/src/index.ts | 67 |
2 files changed, 52 insertions, 23 deletions
diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index 90eaba4c3..e088be21d 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -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" diff --git a/packages/integrations/react/src/index.ts b/packages/integrations/react/src/index.ts index e0149e8e7..62803e788 100644 --- a/packages/integrations/react/src/index.ts +++ b/packages/integrations/react/src/index.ts @@ -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__`, '/'); |