Skip to content

Commit

Permalink
feat: support new React Compiler target option (#374)
Browse files Browse the repository at this point in the history
Co-authored-by: Arnaud Barré <arnaud.barre@carbometrix.com>
  • Loading branch information
poteto and ArnaudBarre authored Oct 16, 2024
1 parent 63b2e38 commit 7a7e339
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 73 deletions.
27 changes: 27 additions & 0 deletions packages/plugin-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

## Unreleased

### React Compiler runtimeModule option removed

React Compiler was updated to accept a `target` option and `runtimeModule` was removed. vite-plugin-react will still detect `runtimeModule` for backwards compatibility.

When using a custom `runtimeModule` or `target !== '19'`, the plugin will not try to pre-optimize `react/compiler-runtime` dependency.

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.

Here is the configuration to use the compiler with React 18 and correct source maps in development:

```bash
npm install react-compiler-runtime
```

```ts
export default defineConfig(({ command }) => {
const babelPlugins = [['babel-plugin-react-compiler', { target: '18' }]]
if (command === 'serve') {
babelPlugins.push(['@babel/plugin-transform-react-jsx-development', {}])
}

return {
plugins: [react({ babel: { plugins: babelPlugins } })],
}
})
````

## 4.3.2 (2024-09-29)

Ignore directive sourcemap error [#369](https://github.com/vitejs/vite-plugin-react/issues/369)
Expand Down
43 changes: 27 additions & 16 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
// Required for esbuild.jsxDev to provide correct line numbers
// This crates issues the react compiler because the re-order is too important
// People should use @babel/plugin-transform-react-jsx-development to get back good line numbers
retainLines: hasCompiler(plugins)
? false
: !isProduction && isJSX && opts.jsxRuntime !== 'classic',
retainLines:
getReactCompilerPlugin(plugins) != null
? false
: !isProduction && isJSX && opts.jsxRuntime !== 'classic',
parserOpts: {
...babelOptions.parserOpts,
sourceType: 'module',
Expand Down Expand Up @@ -274,8 +275,11 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
const dependencies = ['react', jsxImportDevRuntime, jsxImportRuntime]
const staticBabelPlugins =
typeof opts.babel === 'object' ? opts.babel?.plugins ?? [] : []
if (hasCompilerWithDefaultRuntime(staticBabelPlugins)) {
dependencies.push('react/compiler-runtime')
const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins)
if (reactCompilerPlugin != null) {
const reactCompilerRuntimeModule =
getReactCompilerRuntimeModule(reactCompilerPlugin)
dependencies.push(reactCompilerRuntimeModule)
}

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

function hasCompiler(plugins: ReactBabelOptions['plugins']) {
return plugins.some(
function getReactCompilerPlugin(plugins: ReactBabelOptions['plugins']) {
return plugins.find(
(p) =>
p === 'babel-plugin-react-compiler' ||
(Array.isArray(p) && p[0] === 'babel-plugin-react-compiler'),
)
}

// https://gist.github.com/poteto/37c076bf112a07ba39d0e5f0645fec43
function hasCompilerWithDefaultRuntime(plugins: ReactBabelOptions['plugins']) {
return plugins.some(
(p) =>
p === 'babel-plugin-react-compiler' ||
(Array.isArray(p) &&
p[0] === 'babel-plugin-react-compiler' &&
p[1]?.runtimeModule === undefined),
)
type ReactCompilerRuntimeModule =
| 'react/compiler-runtime' // from react namespace
| 'react-compiler-runtime' // npm package
function getReactCompilerRuntimeModule(
plugin: babelCore.PluginItem,
): ReactCompilerRuntimeModule {
let moduleName: ReactCompilerRuntimeModule = 'react/compiler-runtime'
if (Array.isArray(plugin)) {
if (plugin[1]?.target === '17' || plugin[1]?.target === '18') {
moduleName = 'react-compiler-runtime'
} else if (typeof plugin[1]?.runtimeModule === 'string') {
// backward compatibility from (#374), can be removed in next major
moduleName = plugin[1]?.runtimeModule
}
}
return moduleName
}
20 changes: 0 additions & 20 deletions playground/compiler-react-18/lib/react-compiler-runtime/index.js

This file was deleted.

This file was deleted.

4 changes: 2 additions & 2 deletions playground/compiler-react-18/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
},
"dependencies": {
"react": "^18.3.1",
"react-compiler-runtime": "file:./lib/react-compiler-runtime",
"react-compiler-runtime": "0.0.0-experimental-8d8e73f-20241009",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@babel/plugin-transform-react-jsx-development": "^7.24.7",
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "workspace:*",
"babel-plugin-react-compiler": "^0.0.0-experimental-b12479e-20240926",
"babel-plugin-react-compiler": "0.0.0-experimental-58c2b1c-20241009",
"typescript": "^5.6.2",
"vite": "^5.4.8"
}
Expand Down
9 changes: 1 addition & 8 deletions playground/compiler-react-18/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://gist.github.com/poteto/37c076bf112a07ba39d0e5f0645fec43

// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
return {
server: { port: 8901 /* Should be unique */ },
plugins: [
react({
babel: {
plugins: [
[
'babel-plugin-react-compiler',
{ runtimeModule: 'react-compiler-runtime' },
],
],
plugins: [['babel-plugin-react-compiler', { target: '18' }]],
},
}),
],
Expand Down
2 changes: 1 addition & 1 deletion playground/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "workspace:*",
"babel-plugin-react-compiler": "^0.0.0-experimental-b12479e-20240926",
"babel-plugin-react-compiler": "0.0.0-experimental-58c2b1c-20241009",
"typescript": "^5.6.2",
"vite": "^5.4.8"
}
Expand Down
40 changes: 22 additions & 18 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7a7e339

Please sign in to comment.