Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 21 additions & 34 deletions packages/plugin-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ The default Vite plugin for React projects.

- enable [Fast Refresh](https://www.npmjs.com/package/react-refresh) in development (requires react >= 16.9)
- use the [automatic JSX runtime](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)
- use custom Babel plugins/presets
- small installation size

```js
Expand Down Expand Up @@ -68,56 +67,44 @@ By default, the plugin uses the [automatic JSX runtime](https://legacy.reactjs.o
react({ jsxRuntime: 'classic' })
```

### babel
### reactRefreshHost

The `babel` option lets you add plugins, presets, and [other configuration](https://babeljs.io/docs/en/options) to the Babel transformation performed on each included file.
The `reactRefreshHost` option is only necessary in a module federation context. It enables HMR to work between a remote & host application. In your remote Vite config, you would add your host origin:

```js
react({
babel: {
presets: [...],
// Your plugins run before any built-in transform (eg: Fast Refresh)
plugins: [...],
// Use .babelrc files
babelrc: true,
// Use babel.config.js files
configFile: true,
}
})
react({ reactRefreshHost: 'http://localhost:3000' })
```

Note: When not using plugins, only esbuild is used for production builds, resulting in faster builds.
Under the hood, this simply updates the React Fash Refresh runtime URL from `/@react-refresh` to `http://localhost:3000/@react-refresh` to ensure there is only one Refresh runtime across the whole application. Note that if you define `base` option in the host application, you need to include it in the option, like: `http://localhost:3000/{base}`.

#### Proposed syntax
## React Compiler

If you are using ES syntax that are still in proposal status (e.g. class properties), you can selectively enable them with the `babel.parserOpts.plugins` option:
React Compiler support is available via the exported `reactCompilerPreset` helper, which requires `@rolldown/plugin-babel` and `babel-plugin-react-compiler` as peer dependencies:
Comment thread
sapphi-red marked this conversation as resolved.
Outdated

```js
react({
babel: {
parserOpts: {
plugins: ['decorators-legacy'],
},
},
})
```sh
npm install -D @rolldown/plugin-babel babel-plugin-react-compiler
```

This option does not enable _code transformation_. That is handled by esbuild.

**Note:** TypeScript syntax is handled automatically.
```js
// vite.config.js
import { defineConfig } from 'vite'
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'

Here's the [complete list of Babel parser plugins](https://babeljs.io/docs/en/babel-parser#ecmascript-proposalshttpsgithubcombabelproposals).
export default defineConfig({
plugins: [react(), babel(reactCompilerPreset())],
Comment thread
sapphi-red marked this conversation as resolved.
Outdated
})
```

### reactRefreshHost
The `reactCompilerPreset` accepts an optional options object with the following properties:

The `reactRefreshHost` option is only necessary in a module federation context. It enables HMR to work between a remote & host application. In your remote Vite config, you would add your host origin:
- `compilationMode` — Set to `'annotation'` to only compile components annotated with `"use memo"`.
- `target` — Set to `'17'` or `'18'` to target older React versions (uses `react-compiler-runtime` instead of `react/compiler-runtime`).

```js
react({ reactRefreshHost: 'http://localhost:3000' })
babel(reactCompilerPreset({ compilationMode: 'annotation' }))
```

Under the hood, this simply updates the React Fash Refresh runtime URL from `/@react-refresh` to `http://localhost:3000/@react-refresh` to ensure there is only one Refresh runtime across the whole application. Note that if you define `base` option in the host application, you need to include it in the option, like: `http://localhost:3000/{base}`.

## `@vitejs/plugin-react/preamble`

The package provides `@vitejs/plugin-react/preamble` to initialize HMR runtime from client entrypoint for SSR applications which don't use [`transformIndexHtml` API](https://vite.dev/guide/api-javascript.html#vitedevserver). For example:
Expand Down
24 changes: 17 additions & 7 deletions packages/plugin-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"version": "5.1.4",
"description": "The default Vite plugin for React projects",
"keywords": [
"babel",
"fast refresh",
"react",
"react-refresh",
Expand All @@ -30,6 +29,9 @@
"types"
],
"type": "module",
"imports": {
"#optionalTypes": "./types/optionalTypes.d.ts"
},
"exports": {
".": "./dist/index.js",
"./preamble": "./types/preamble.d.ts"
Expand All @@ -41,24 +43,32 @@
"test-unit": "vitest run"
},
"dependencies": {
"@babel/core": "^7.29.0",
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
"@rolldown/pluginutils": "1.0.0-rc.5",
"@types/babel__core": "^7.20.5"
"@rolldown/pluginutils": "1.0.0-rc.5"
},
"devDependencies": {
"@babel/core": "8.0.0-rc.2",
"@rolldown/plugin-babel": "^0.1.6",
"@vitejs/react-common": "workspace:*",
"babel-plugin-react-compiler": "19.1.0-rc.3",
"babel-plugin-react-compiler": "^1.0.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"rolldown": "1.0.0-rc.5",
"tsdown": "^0.20.3",
"vite": "^8.0.0-beta.16"
},
"peerDependencies": {
"@rolldown/plugin-babel": "^0.1.6",
"babel-plugin-react-compiler": "^1.0.0",
"vite": "^8.0.0"
},
"peerDependenciesMeta": {
"@rolldown/plugin-babel": {
"optional": true
},
"babel-plugin-react-compiler": {
"optional": true
}
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
Expand Down
2 changes: 0 additions & 2 deletions packages/plugin-react/src/babel.d.ts

This file was deleted.

Loading
Loading