Skip to content

Commit 7a7e339

Browse files
potetoArnaudBarre
andauthored
feat: support new React Compiler target option (#374)
Co-authored-by: Arnaud Barré <[email protected]>
1 parent 63b2e38 commit 7a7e339

File tree

8 files changed

+80
-73
lines changed

8 files changed

+80
-73
lines changed

packages/plugin-react/CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@
22

33
## Unreleased
44

5+
### React Compiler runtimeModule option removed
6+
7+
React Compiler was updated to accept a `target` option and `runtimeModule` was removed. vite-plugin-react will still detect `runtimeModule` for backwards compatibility.
8+
9+
When using a custom `runtimeModule` or `target !== '19'`, the plugin will not try to pre-optimize `react/compiler-runtime` dependency.
10+
11+
The [react-compiler-runtime](https://www.npmjs.com/package/react-compiler-runtime) is now available on npm can be used instead of the local shim for people using the compiler with React < 19.
12+
13+
Here is the configuration to use the compiler with React 18 and correct source maps in development:
14+
15+
```bash
16+
npm install react-compiler-runtime
17+
```
18+
19+
```ts
20+
export default defineConfig(({ command }) => {
21+
const babelPlugins = [['babel-plugin-react-compiler', { target: '18' }]]
22+
if (command === 'serve') {
23+
babelPlugins.push(['@babel/plugin-transform-react-jsx-development', {}])
24+
}
25+
26+
return {
27+
plugins: [react({ babel: { plugins: babelPlugins } })],
28+
}
29+
})
30+
````
31+
532
## 4.3.2 (2024-09-29)
633

734
Ignore directive sourcemap error [#369](https://github.com/vitejs/vite-plugin-react/issues/369)

packages/plugin-react/src/index.ts

+27-16
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
237237
// Required for esbuild.jsxDev to provide correct line numbers
238238
// This crates issues the react compiler because the re-order is too important
239239
// People should use @babel/plugin-transform-react-jsx-development to get back good line numbers
240-
retainLines: hasCompiler(plugins)
241-
? false
242-
: !isProduction && isJSX && opts.jsxRuntime !== 'classic',
240+
retainLines:
241+
getReactCompilerPlugin(plugins) != null
242+
? false
243+
: !isProduction && isJSX && opts.jsxRuntime !== 'classic',
243244
parserOpts: {
244245
...babelOptions.parserOpts,
245246
sourceType: 'module',
@@ -274,8 +275,11 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
274275
const dependencies = ['react', jsxImportDevRuntime, jsxImportRuntime]
275276
const staticBabelPlugins =
276277
typeof opts.babel === 'object' ? opts.babel?.plugins ?? [] : []
277-
if (hasCompilerWithDefaultRuntime(staticBabelPlugins)) {
278-
dependencies.push('react/compiler-runtime')
278+
const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins)
279+
if (reactCompilerPlugin != null) {
280+
const reactCompilerRuntimeModule =
281+
getReactCompilerRuntimeModule(reactCompilerPlugin)
282+
dependencies.push(reactCompilerRuntimeModule)
279283
}
280284

281285
const viteReactRefresh: Plugin = {
@@ -377,21 +381,28 @@ function defined<T>(value: T | undefined): value is T {
377381
return value !== undefined
378382
}
379383

380-
function hasCompiler(plugins: ReactBabelOptions['plugins']) {
381-
return plugins.some(
384+
function getReactCompilerPlugin(plugins: ReactBabelOptions['plugins']) {
385+
return plugins.find(
382386
(p) =>
383387
p === 'babel-plugin-react-compiler' ||
384388
(Array.isArray(p) && p[0] === 'babel-plugin-react-compiler'),
385389
)
386390
}
387391

388-
// https://gist.github.com/poteto/37c076bf112a07ba39d0e5f0645fec43
389-
function hasCompilerWithDefaultRuntime(plugins: ReactBabelOptions['plugins']) {
390-
return plugins.some(
391-
(p) =>
392-
p === 'babel-plugin-react-compiler' ||
393-
(Array.isArray(p) &&
394-
p[0] === 'babel-plugin-react-compiler' &&
395-
p[1]?.runtimeModule === undefined),
396-
)
392+
type ReactCompilerRuntimeModule =
393+
| 'react/compiler-runtime' // from react namespace
394+
| 'react-compiler-runtime' // npm package
395+
function getReactCompilerRuntimeModule(
396+
plugin: babelCore.PluginItem,
397+
): ReactCompilerRuntimeModule {
398+
let moduleName: ReactCompilerRuntimeModule = 'react/compiler-runtime'
399+
if (Array.isArray(plugin)) {
400+
if (plugin[1]?.target === '17' || plugin[1]?.target === '18') {
401+
moduleName = 'react-compiler-runtime'
402+
} else if (typeof plugin[1]?.runtimeModule === 'string') {
403+
// backward compatibility from (#374), can be removed in next major
404+
moduleName = plugin[1]?.runtimeModule
405+
}
406+
}
407+
return moduleName
397408
}

playground/compiler-react-18/lib/react-compiler-runtime/index.js

-20
This file was deleted.

playground/compiler-react-18/lib/react-compiler-runtime/package.json

-8
This file was deleted.

playground/compiler-react-18/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
},
1010
"dependencies": {
1111
"react": "^18.3.1",
12-
"react-compiler-runtime": "file:./lib/react-compiler-runtime",
12+
"react-compiler-runtime": "0.0.0-experimental-8d8e73f-20241009",
1313
"react-dom": "^18.3.1"
1414
},
1515
"devDependencies": {
1616
"@babel/plugin-transform-react-jsx-development": "^7.24.7",
1717
"@types/react": "^18.3.10",
1818
"@types/react-dom": "^18.3.0",
1919
"@vitejs/plugin-react": "workspace:*",
20-
"babel-plugin-react-compiler": "^0.0.0-experimental-b12479e-20240926",
20+
"babel-plugin-react-compiler": "0.0.0-experimental-58c2b1c-20241009",
2121
"typescript": "^5.6.2",
2222
"vite": "^5.4.8"
2323
}

playground/compiler-react-18/vite.config.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
import { defineConfig } from 'vite'
22
import react from '@vitejs/plugin-react'
33

4-
// https://gist.github.com/poteto/37c076bf112a07ba39d0e5f0645fec43
5-
64
// https://vitejs.dev/config/
75
export default defineConfig(({ command }) => {
86
return {
97
server: { port: 8901 /* Should be unique */ },
108
plugins: [
119
react({
1210
babel: {
13-
plugins: [
14-
[
15-
'babel-plugin-react-compiler',
16-
{ runtimeModule: 'react-compiler-runtime' },
17-
],
18-
],
11+
plugins: [['babel-plugin-react-compiler', { target: '18' }]],
1912
},
2013
}),
2114
],

playground/compiler/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"@types/react": "^18.3.10",
1717
"@types/react-dom": "^18.3.0",
1818
"@vitejs/plugin-react": "workspace:*",
19-
"babel-plugin-react-compiler": "^0.0.0-experimental-b12479e-20240926",
19+
"babel-plugin-react-compiler": "0.0.0-experimental-58c2b1c-20241009",
2020
"typescript": "^5.6.2",
2121
"vite": "^5.4.8"
2222
}

pnpm-lock.yaml

+22-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)