diff options
Diffstat (limited to 'packages/integrations/react')
-rw-r--r-- | packages/integrations/react/CHANGELOG.md | 45 | ||||
-rw-r--r-- | packages/integrations/react/README.md | 33 | ||||
-rw-r--r-- | packages/integrations/react/package.json | 14 | ||||
-rw-r--r-- | packages/integrations/react/src/index.ts | 66 | ||||
-rw-r--r-- | packages/integrations/react/tsconfig.json | 2 |
5 files changed, 116 insertions, 44 deletions
diff --git a/packages/integrations/react/CHANGELOG.md b/packages/integrations/react/CHANGELOG.md index 403ed56b5..e68872a46 100644 --- a/packages/integrations/react/CHANGELOG.md +++ b/packages/integrations/react/CHANGELOG.md @@ -1,5 +1,50 @@ # @astrojs/react +## 3.0.0-beta.3 + +### Minor Changes + +- [#8082](https://github.com/withastro/astro/pull/8082) [`16a3fdf93`](https://github.com/withastro/astro/commit/16a3fdf93165a1a0404c1db0973871345b2c591b) Thanks [@matthewp](https://github.com/matthewp)! - Optionally parse React slots as React children. + + This adds a new configuration option for the React integration `experimentalReactChildren`: + + ```js + export default { + integrations: [ + react({ + experimentalReactChildren: true, + }), + ], + }; + ``` + + With this enabled, children passed to React from Astro components via the default slot are parsed as React components. + + This enables better compatibility with certain React components which manipulate their children. + +## 3.0.0-beta.2 + +### Patch Changes + +- Updated dependencies [[`2aa6d8ace`](https://github.com/withastro/astro/commit/2aa6d8ace398a41c2dec5473521d758816b08191)]: + - @astrojs/internal-helpers@0.2.0-beta.1 + +## 3.0.0-beta.1 + +### Major Changes + +- [#7924](https://github.com/withastro/astro/pull/7924) [`519a1c4e8`](https://github.com/withastro/astro/commit/519a1c4e8407c7abcb8d879b67a9f4b960652cae) Thanks [@matthewp](https://github.com/matthewp)! - Support for React Refresh + + The React integration now fully supports React Refresh and is backed by `@vitejs/plugin-react`. + + Also included in this change are new `include` and `exclude` config options. Use these if you want to use React alongside another JSX framework; include specifies files to be compiled for React and `exclude` does the opposite. + +## 3.0.0-beta.0 + +### Major Changes + +- [`1eae2e3f7`](https://github.com/withastro/astro/commit/1eae2e3f7d693c9dfe91c8ccfbe606d32bf2fb81) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove support for Node 16. The lowest supported version by Astro and all integrations is now v18.14.1. As a reminder, Node 16 will be deprecated on the 11th September 2023. + ## 2.3.2 ### Patch Changes diff --git a/packages/integrations/react/README.md b/packages/integrations/react/README.md index 8009972b3..aca6eba7d 100644 --- a/packages/integrations/react/README.md +++ b/packages/integrations/react/README.md @@ -63,6 +63,39 @@ To use your first React component in Astro, head to our [UI framework documentat ## Options +### Combining multiple JSX frameworks + +When you are using multiple JSX frameworks (React, Preact, Solid) in the same project, Astro needs to determine which JSX framework-specific transformations should be used for each of your components. If you have only added one JSX framework integration to your project, no extra configuration is needed. + +Use the `include` (required) and `exclude` (optional) configuration options to specify which files belong to which framework. Provide an array of files and/or folders to `include` for each framework you are using. Wildcards may be used to include multiple file paths. + +We recommend placing common framework components in the same folder (e.g. `/components/react/` and `/components/solid/`) to make specifying your includes easier, but this is not required: + +```js +import { defineConfig } from 'astro/config'; +import preact from '@astrojs/preact'; +import react from '@astrojs/react'; +import svelte from '@astrojs/svelte'; +import vue from '@astrojs/vue'; +import solid from '@astrojs/solid-js'; + +export default defineConfig({ + // Enable many frameworks to support all different kinds of components. + // No `include` is needed if you are only using a single JSX framework! + integrations: [ + preact({ + include: ['**/preact/*'] + }), + react({ + include: ['**/react/*'] + }), + solid({ + include: ['**/solid/*'], + }), + ] +}); +``` + ### Children parsing Children passed into a React component from an Astro component are parsed as plain strings, not React nodes. diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index 682811c7c..9ac1b0d35 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/react", "description": "Use React components within Astro", - "version": "2.3.2", + "version": "3.0.0-beta.3", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -26,8 +26,7 @@ "./server.js": "./server.js", "./server-v17.js": "./server-v17.js", "./package.json": "./package.json", - "./jsx-runtime": "./jsx-runtime.js", - "./vnode-children.js": "./vnode-children.js" + "./jsx-runtime": "./jsx-runtime.js" }, "files": [ "dist", @@ -37,8 +36,7 @@ "jsx-runtime.js", "server.js", "server-v17.js", - "static-html.js", - "vnode-children.js" + "static-html.js" ], "scripts": { "build": "astro-scripts build \"src/**/*.ts\" && tsc", @@ -46,8 +44,8 @@ "dev": "astro-scripts dev \"src/**/*.ts\"" }, "dependencies": { - "@babel/core": "^7.22.5", - "@babel/plugin-transform-react-jsx": "^7.22.5", + "@astrojs/internal-helpers": "0.2.0-beta.1", + "@vitejs/plugin-react": "^4.0.3", "ultrahtml": "^1.2.0" }, "devDependencies": { @@ -68,6 +66,6 @@ "react-dom": "^17.0.2 || ^18.0.0" }, "engines": { - "node": ">=16.12.0" + "node": ">=18.14.1" } } diff --git a/packages/integrations/react/src/index.ts b/packages/integrations/react/src/index.ts index d1cd7c4e6..1cc200bc3 100644 --- a/packages/integrations/react/src/index.ts +++ b/packages/integrations/react/src/index.ts @@ -1,7 +1,15 @@ import type { AstroIntegration } from 'astro'; import { version as ReactVersion } from 'react-dom'; +import react, { type Options as ViteReactPluginOptions } from '@vitejs/plugin-react'; +import { appendForwardSlash } from '@astrojs/internal-helpers/path'; import type * as vite from 'vite'; +export type ReactIntegrationOptions = Pick<ViteReactPluginOptions, 'include' | 'exclude'> & { + experimentalReactChildren?: boolean; +}; + +const FAST_REFRESH_PREAMBLE = react.preambleCode; + function getRenderer() { return { name: '@astrojs/react', @@ -11,29 +19,6 @@ function getRenderer() { 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', - } - ), - ], - }; - }, }; } @@ -59,7 +44,11 @@ function optionsPlugin(experimentalReactChildren: boolean): vite.Plugin { }; } -function getViteConfiguration(experimentalReactChildren: boolean) { +function getViteConfiguration({ + include, + exclude, + experimentalReactChildren, +}: ReactIntegrationOptions = {}) { return { optimizeDeps: { include: [ @@ -77,8 +66,9 @@ function getViteConfiguration(experimentalReactChildren: boolean) { : '@astrojs/react/server-v17.js', ], }, + plugins: [react({ include, exclude }), optionsPlugin(!!experimentalReactChildren)], resolve: { - dedupe: ['react', 'react-dom'], + dedupe: ['react', 'react-dom', 'react-dom/server'], }, ssr: { external: ReactVersion.startsWith('18.') @@ -93,23 +83,29 @@ function getViteConfiguration(experimentalReactChildren: boolean) { 'use-immer', ], }, - plugins: [optionsPlugin(experimentalReactChildren)], }; } -export type ReactIntegrationOptions = { - experimentalReactChildren: boolean; -}; - -export default function ( - { experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false } -): AstroIntegration { +export default function ({ + include, + exclude, + experimentalReactChildren, +}: ReactIntegrationOptions = {}): AstroIntegration { return { name: '@astrojs/react', hooks: { - 'astro:config:setup': ({ addRenderer, updateConfig }) => { + 'astro:config:setup': ({ config, command, addRenderer, updateConfig, injectScript }) => { addRenderer(getRenderer()); - updateConfig({ vite: getViteConfiguration(experimentalReactChildren) }); + updateConfig({ + vite: getViteConfiguration({ include, exclude, experimentalReactChildren }), + }); + if (command === 'dev') { + const preamble = FAST_REFRESH_PREAMBLE.replace( + `__BASE__`, + appendForwardSlash(config.base) + ); + injectScript('before-hydration', preamble); + } }, }, }; diff --git a/packages/integrations/react/tsconfig.json b/packages/integrations/react/tsconfig.json index 64d4ef454..af1b43564 100644 --- a/packages/integrations/react/tsconfig.json +++ b/packages/integrations/react/tsconfig.json @@ -5,6 +5,6 @@ "allowJs": true, "module": "ES2022", "outDir": "./dist", - "target": "ES2021" + "target": "ES2022" } } |