diff --git a/packages/plugin-react/README.md b/packages/plugin-react/README.md index 563a81142..807050cd9 100644 --- a/packages/plugin-react/README.md +++ b/packages/plugin-react/README.md @@ -79,13 +79,48 @@ Under the hood, this simply updates the React Fash Refresh runtime URL from `/@r ## React Compiler -[React Compiler](https://react.dev/learn/react-compiler) support is available via the exported `reactCompilerPreset` helper, which requires [`@rolldown/plugin-babel`](https://npmx.dev/package/@rolldown/plugin-babel) and [`babel-plugin-react-compiler`](https://npmx.dev/package/babel-plugin-react-compiler) and [`@babel/core`](https://npmx.dev/package/@babel/core) as peer dependencies: +### Rust React Compiler + +> [!WARNING] +> Native React Compiler support is experimental. + +The `compiler` option uses [`oxc-transform-react`](https://npmx.dev/package/oxc-transform-react), a Rust port of [React Compiler](https://react.dev/learn/react-compiler), which must be installed as an optional peer dependency: + +```sh +npm install -D oxc-transform-react +``` + +```js +// vite.config.js +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react({ compiler: true })], +}) +``` + +The `compiler` option also accepts [React Compiler options](https://react.dev/reference/react-compiler/configuration): + +```js +react({ compiler: { compilationMode: 'annotation' } }) +``` + +Source maps are generated by default during development. For production builds, the default follows Vite's [`build.sourcemap`](https://vite.dev/config/build-options.html#build-sourcemap) option. They can be disabled explicitly to improve transform performance: + +```js +react({ compiler: { sourcemap: false } }) +``` + +### Babel React Compiler + +React Compiler can also be used through Babel with the exported `reactCompilerPreset` helper. This requires [`@rolldown/plugin-babel`](https://npmx.dev/package/@rolldown/plugin-babel), [`babel-plugin-react-compiler`](https://npmx.dev/package/babel-plugin-react-compiler), and [`@babel/core`](https://npmx.dev/package/@babel/core) as peer dependencies: ```sh npm install -D @rolldown/plugin-babel @babel/core babel-plugin-react-compiler ``` -If you are using TypeScript, you will also need to install [`@types/babel__core`](https://npmx.dev/package/@types/babel__core): +If you are using TypeScript with Babel, you will also need to install [`@types/babel__core`](https://npmx.dev/package/@types/babel__core): ```sh npm install -D @types/babel__core diff --git a/packages/plugin-react/package.json b/packages/plugin-react/package.json index bb838ba24..dd5bc0746 100644 --- a/packages/plugin-react/package.json +++ b/packages/plugin-react/package.json @@ -50,6 +50,7 @@ "@rolldown/plugin-babel": "^0.2.3", "@vitejs/react-common": "workspace:*", "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.144.0", "react": "^19.2.8", "react-dom": "^19.2.8", "rolldown": "^1.2.3", @@ -59,6 +60,7 @@ "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.144.0", "vite": "^8.0.0" }, "peerDependenciesMeta": { @@ -67,6 +69,9 @@ }, "babel-plugin-react-compiler": { "optional": true + }, + "oxc-transform-react": { + "optional": true } }, "engines": { diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 9a9019b31..bab8aa665 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -14,7 +14,8 @@ import { } from '@vitejs/react-common' import type { Plugin, ServerOptions } from 'vite' import { reactRefreshWrapperPlugin } from 'vite/internal' -import { reactCompilerPreset } from './reactCompilerPreset' +import type { ReactCompilerOptions } from '#optionalTypes' +import { defaultCodeFilter, reactCompilerPreset } from './reactCompilerPreset' const _dirname = dirname(fileURLToPath(import.meta.url)) const refreshRuntimePath = join(_dirname, 'refresh-runtime.js') @@ -52,6 +53,12 @@ export interface Options { * reactRefreshHost: 'http://localhost:3000' */ reactRefreshHost?: string + /** + * Enable React Compiler with its default options or configure it. + * This requires `oxc-transform-react` to be installed. + * @default false + */ + compiler?: boolean | ReactCompilerOptions } const defaultIncludeRE = /\.[tj]sx?$/ @@ -251,7 +258,7 @@ export default function viteReact(opts: Options = {}): Plugin[] { }, } - return [ + const plugins = [ viteBabel, viteRefreshWrapper, viteConfigPost, @@ -262,11 +269,111 @@ export default function viteReact(opts: Options = {}): Plugin[] { isEnabled: () => !skipFastRefresh && !isBundledDev, }), ] + + if (opts.compiler) { + plugins.unshift( + createReactCompilerPlugin( + opts.compiler === true ? {} : opts.compiler, + include, + exclude, + ), + ) + } + + return plugins +} + +function createReactCompilerPlugin( + options: ReactCompilerOptions, + include: NonNullable, + exclude: NonNullable, +): Plugin { + const { sourcemap: sourcemapOption, ...compilerOptions } = options + let sourcemap = sourcemapOption ?? true + let compiler: typeof import('oxc-transform-react') | undefined + const runtime = + compilerOptions.target === '17' || compilerOptions.target === '18' + ? 'react-compiler-runtime' + : 'react/compiler-runtime' + + const loadCompiler = async ( + onError: (message: string) => never, + ): Promise => { + if (compiler) return compiler + + try { + return (compiler = await import('oxc-transform-react')) + } catch (error) { + return onError( + `React Compiler requires the optional \`oxc-transform-react\` package. Install it in your project before enabling \`react({ compiler: true })\`.${ + error instanceof Error ? `\n${error.message}` : '' + }`, + ) + } + } + + return { + name: 'vite:react-compiler', + enforce: 'pre', + async config() { + await loadCompiler((message) => this.error(message)) + return { + optimizeDeps: { + include: [runtime], + }, + } + }, + configResolved(config) { + sourcemap = + sourcemapOption ?? + (config.command === 'build' ? !!config.build.sourcemap : true) + }, + applyToEnvironment: (env) => env.config.consumer === 'client', + transform: { + filter: { + id: { + include: makeIdFiltersToMatchWithQuery(include), + exclude: makeIdFiltersToMatchWithQuery(exclude), + }, + code: + compilerOptions.compilationMode === 'annotation' + ? /['"]use memo['"]/ + : defaultCodeFilter, + }, + async handler(code, id) { + // The config hook is not called when the plugin is used with Rolldown directly. + const { transform } = + compiler ?? (await loadCompiler((message) => this.error(message))) + + const result = await transform(id.split('?')[0]!, code, { + jsx: 'preserve', + reactCompiler: compilerOptions, + sourcemap, + }) + const diagnostics = result.errors.map( + (error) => + `${error.message}${error.codeframe ? `\n${error.codeframe}` : ''}`, + ) + + if (result.fatal) { + this.error( + diagnostics.join('\n\n') || 'React Compiler transform failed.', + ) + } + for (const diagnostic of diagnostics) { + this.warn(diagnostic) + } + + return { code: result.code, map: result.map } + }, + }, + } } viteReact.preambleCode = preambleCode export { reactCompilerPreset } +export type { ReactCompilerOptions } // Compat for require function viteReactForCjs(this: unknown, options: Options): Plugin[] { diff --git a/packages/plugin-react/tests/reactCompiler.test.ts b/packages/plugin-react/tests/reactCompiler.test.ts new file mode 100644 index 000000000..13da2c8a9 --- /dev/null +++ b/packages/plugin-react/tests/reactCompiler.test.ts @@ -0,0 +1,139 @@ +import path from 'node:path' +import { type Plugin, rolldown } from 'rolldown' +import { describe, expect, test } from 'vitest' +import pluginReact, { + type Options, + type ReactCompilerOptions, +} from '../src/index.ts' + +describe('compiler option', () => { + test('compiles React components', async () => { + const output = await bundle( + { compiler: true }, + ` + export function App({ name }: { name: string }) { + return
{name}
+ } + `, + ) + + expect(output.code).toContain('react/compiler-runtime') + expect(output.code).toMatch(/\bc\(2\)/) + expect( + output.map?.sources.some((source) => source.endsWith('entry.tsx')), + ).toBe(true) + }) + + test('forwards compiler options', async () => { + const code = ` + export function App({ name }) { + return
{name}
+ } + ` + const unannotated = await bundle( + { compiler: { compilationMode: 'annotation' } }, + code, + ) + const annotated = await bundle( + { compiler: { compilationMode: 'annotation' } }, + ` + export function App({ name }) { + 'use memo' + return
{name}
+ } + `, + ) + const react18 = await bundle({ compiler: { target: '18' } }, code) + + expect(unannotated.code).not.toContain('react/compiler-runtime') + expect(annotated.code).toContain('react/compiler-runtime') + expect(react18.code).toContain('react-compiler-runtime') + }) + + test('uses the React plugin filters', async () => { + const output = await bundle( + { compiler: true, exclude: /entry\.tsx$/ }, + `export function App({ name }) { return
{name}
}`, + ) + + expect(output.code).not.toContain('react/compiler-runtime') + }) + + test('uses the Vite build sourcemap setting by default', async () => { + expect((await transformWithBuildConfig({}, false)).map).toBeFalsy() + expect((await transformWithBuildConfig({}, true)).map).toBeTruthy() + expect( + (await transformWithBuildConfig({ sourcemap: false }, true)).map, + ).toBeFalsy() + expect( + (await transformWithBuildConfig({ sourcemap: true }, false)).map, + ).toBeTruthy() + }) +}) + +async function transformWithBuildConfig( + compiler: ReactCompilerOptions, + buildSourcemap: boolean, +) { + const plugin = pluginReact({ compiler }).find( + (plugin) => plugin.name === 'vite:react-compiler', + )! + const context = { + error(message: unknown): never { + throw new Error(String(message)) + }, + warn() {}, + } + + if (typeof plugin.config !== 'function') + throw new Error('Missing config hook') + await plugin.config.call( + context as any, + {}, + { command: 'build', mode: 'production' }, + ) + + if (typeof plugin.configResolved !== 'function') { + throw new Error('Missing configResolved hook') + } + await plugin.configResolved.call( + context as any, + { + command: 'build', + build: { sourcemap: buildSourcemap }, + } as any, + ) + + if (typeof plugin.transform !== 'object') { + throw new Error('Missing transform hook') + } + return plugin.transform.handler.call( + context as any, + `export function App({ name }) { return
{name}
}`, + '/entry.tsx', + ) +} + +async function bundle(options: Options, code: string) { + const entry = '/entry.tsx' + const build = await rolldown({ + input: entry, + plugins: [virtualFilePlugin(entry, code), pluginReact(options)], + external: [/^react(\/|$)/, /^react-compiler-runtime$/], + }) + const { output } = await build.generate({ format: 'esm', sourcemap: true }) + return output[0] +} + +function virtualFilePlugin(entry: string, code: string): Plugin { + return { + name: 'virtual-file', + resolveId(id, importer) { + const baseDir = importer ? path.posix.dirname(importer) : '/' + if (path.posix.resolve(baseDir, id) === entry) return entry + }, + load(id) { + if (id === entry) return code + }, + } +} diff --git a/packages/plugin-react/types/optionalTypes.d.ts b/packages/plugin-react/types/optionalTypes.d.ts index f780e933f..18975331f 100644 --- a/packages/plugin-react/types/optionalTypes.d.ts +++ b/packages/plugin-react/types/optionalTypes.d.ts @@ -4,9 +4,19 @@ import type * as pluginBabel from '@rolldown/plugin-babel' // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error import type * as babelPluginReactCompiler from 'babel-plugin-react-compiler' +// @ts-ignore --- `oxc-transform-react` is an optional peer dependency, so this may cause an error +import type * as oxcTransformReact from 'oxc-transform-react' // @ts-ignore --- `@rolldown/plugin-babel` is an optional peer dependency, so this may cause an error export type RolldownBabelPreset = pluginBabel.RolldownBabelPreset // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error export type ReactCompilerBabelPluginOptions = babelPluginReactCompiler.PluginOptions +// @ts-ignore --- `oxc-transform-react` is an optional peer dependency, so this may cause an error +export type ReactCompilerOptions = oxcTransformReact.ReactCompilerOptions & { + /** + * Generate a source map for the compiler transform. + * @default true during development, `build.sourcemap` during builds + */ + sourcemap?: boolean +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f560b3b5e..0b9d10ece 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,9 @@ importers: babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 + oxc-transform-react: + specifier: ^0.144.0 + version: 0.144.0 react: specifier: ^19.2.8 version: 19.2.8 @@ -2125,6 +2128,128 @@ packages: '@oxc-project/types@0.143.0': resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} + '@oxc-transform-react/binding-android-arm-eabi@0.144.0': + resolution: {integrity: sha512-PpHbQKiNZgvUg0ccpffsHRZDEIoQOVUqy8XO6Ug14wj2Udzt5ugjw3AqSpgffqepN7oAPl7VzjSaiKG7k/YV8g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-transform-react/binding-android-arm64@0.144.0': + resolution: {integrity: sha512-X50TG9qTB0xgMVGn4UfAWtb5hLyC2xofh9k2u2gAvE6N3jW5zlootIlYIJ9SWnmwntj9SgZ3CbH9GrQczlc4tg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-transform-react/binding-darwin-arm64@0.144.0': + resolution: {integrity: sha512-Lb4M7FtwjzVBuiz8gS9sf0paeafUWRZTHUCVlB0HfCVMl6eTZ5vP4/koAgyYY3Ocw/5ccTqqWnlC1vBSMUOMgw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-transform-react/binding-darwin-x64@0.144.0': + resolution: {integrity: sha512-yTMBB0mUJDkyGZ5+10glqTXx1fTIsEbIxwGY9MihtC5m1RIxA8G7/tnoWwZbRmadZQUpDeRgk0sq6vE5nhSAmQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-transform-react/binding-freebsd-x64@0.144.0': + resolution: {integrity: sha512-eljkRMUuTqpFfeZSh3RxJlWl95rl2ySn+9UySXllbKF36JmZ+NHkTBXdYzyH9nCP8cyguLAg1vclEDbUSrLIhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-transform-react/binding-linux-arm-gnueabihf@0.144.0': + resolution: {integrity: sha512-QiX/kQ0zUlI7cdMzq65JdpwxVTsol47iZaM+5scKPZZSe2d6mvlvhyUq42r1wvmGMNC3R5we5UfzB53Rc6qZqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform-react/binding-linux-arm-musleabihf@0.144.0': + resolution: {integrity: sha512-Q9WQLcCZciwcPYZFZUjSFj/QZBV3oCiP9716JrJcmHpwAhSOHECPkAtI93gmrzkfBda0fG3FBaoHMNNTWhXOlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform-react/binding-linux-arm64-gnu@0.144.0': + resolution: {integrity: sha512-SiKauC0K4mvNbiSaEbwPnZgrgYSUkbZUllpJuVTxxlECrl3YAGRGkO6V3NSPFvFJXZEYFuAoPJ9+iVjBzf62Sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform-react/binding-linux-arm64-musl@0.144.0': + resolution: {integrity: sha512-iwUOr+tEJ5OCqCSKmx58NAvVT7iX8lTV2SqZWqg0n41u5zIb3xtD+7PshDhpydTglrB7SkEZJRCI8cthNx9bKg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform-react/binding-linux-ppc64-gnu@0.144.0': + resolution: {integrity: sha512-ovuH1kJRUZrZiGrBpo4HRI8M/dw/qtzkyBRAzsgIAx3K0QRBjNlsvr+cQApipGZgQMmD7bk5a8rLh4b5mP8cHw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-transform-react/binding-linux-riscv64-gnu@0.144.0': + resolution: {integrity: sha512-EVTrc51rseSVTXBB/a+fs2Jlfi3Q5BoDHBPAohIANXsF4UPIrEF0MePp1dS41huXAREUsRVKpx62891xaEtY5w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-transform-react/binding-linux-riscv64-musl@0.144.0': + resolution: {integrity: sha512-CGDSWylxJOAfZ0bFl9mFnXSxVgVxhlK51iUFmz3pzRnCiz9XadrADL6+NkrCDO1/YBDZoHbnWefqD5NTedJFug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-transform-react/binding-linux-s390x-gnu@0.144.0': + resolution: {integrity: sha512-DF+FZClbHj3R13NKT/qfgNRG6azpzO0h/uXXKn9zaE5lvwRzZauUbBE+ixif2qe8z96ztn4Yngea32UdkucgOw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-transform-react/binding-linux-x64-gnu@0.144.0': + resolution: {integrity: sha512-35mYvRYJpIjw70tK5NagEkIeVAu6wkgBZg5AfrFYKxNmbUmLR6kbv7Awhh+9yVvf6t18TGVkJdkic2zB7dc7Qw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform-react/binding-linux-x64-musl@0.144.0': + resolution: {integrity: sha512-GDRz1OCFiNYv0C2FZBVXOWTpI3Qw/tCKIKzAVb4q0Ma0341YSNk5VJ1Ou6bIocgN9o9hjJdYK2A6zpt8dcDGvg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform-react/binding-openharmony-arm64@0.144.0': + resolution: {integrity: sha512-d0YOi9u0GeUdmwYRhpn8mQZEaVbOR5JKbfHXmcgCSOzgRc6W1dy6cVnDnlr8ScEKNSnBdzjkKb7B6IO0eo0JtQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform-react/binding-win32-arm64-msvc@0.144.0': + resolution: {integrity: sha512-gpLta9fcH7qpwFGYxEknzjIt4r4nZM5dzJmfMF46AIds1A6iaUAxqwopPzIBiUsE8ewaxCh0Tg3Gpuk4d1/Y3g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-transform-react/binding-win32-ia32-msvc@0.144.0': + resolution: {integrity: sha512-vhAo4JJAWYpW2OJ9Wk/Z+fe31fIZLWFXkAAzduz8WRW7PGjNddk2ohmMm49bOsVCOIjC4Yerx8PKbtH1RKDeMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-transform-react/binding-win32-x64-msvc@0.144.0': + resolution: {integrity: sha512-3RywrPVBMrJ3B76j2KN2r9hIS4r3ESM15MafvG0OMV0YGgVWXu1bWSRmAGjKB2DcTO2KD5gev759XTJTgsynIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@oxfmt/binding-android-arm-eabi@0.62.0': resolution: {integrity: sha512-pdsv0C4gPjJ8H1+sd8u0BDx+yLACTL+rgeMIOL1ln4ihSnhw8CWXtYWgvcSkyTfgGBIzFKab+d8rx9Xl4en/Kw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4191,6 +4316,10 @@ packages: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} + oxc-transform-react@0.144.0: + resolution: {integrity: sha512-98G1A7nteiSUshb3mN7kXqd+pBzelB6O+cbvmvdEXAhzfgVER6vDJs9GtGE/g+gaRQfs1bnAPk/mQCguAKAmvw==} + engines: {node: ^20.19.0 || >=22.12.0} + oxfmt@0.62.0: resolution: {integrity: sha512-vxgGHTmnDU9j4CX7dDBLzxgmHxfda/yPcgJkGCMUSCwRmz+euo/V08xXLNgXTeqAB9Fhf3Pe2nO1RNKLCVgphQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -5626,6 +5755,63 @@ snapshots: '@oxc-project/types@0.143.0': {} + '@oxc-transform-react/binding-android-arm-eabi@0.144.0': + optional: true + + '@oxc-transform-react/binding-android-arm64@0.144.0': + optional: true + + '@oxc-transform-react/binding-darwin-arm64@0.144.0': + optional: true + + '@oxc-transform-react/binding-darwin-x64@0.144.0': + optional: true + + '@oxc-transform-react/binding-freebsd-x64@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-arm-gnueabihf@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-arm-musleabihf@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-arm64-gnu@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-arm64-musl@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-ppc64-gnu@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-riscv64-gnu@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-riscv64-musl@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-s390x-gnu@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-x64-gnu@0.144.0': + optional: true + + '@oxc-transform-react/binding-linux-x64-musl@0.144.0': + optional: true + + '@oxc-transform-react/binding-openharmony-arm64@0.144.0': + optional: true + + '@oxc-transform-react/binding-win32-arm64-msvc@0.144.0': + optional: true + + '@oxc-transform-react/binding-win32-ia32-msvc@0.144.0': + optional: true + + '@oxc-transform-react/binding-win32-x64-msvc@0.144.0': + optional: true + '@oxfmt/binding-android-arm-eabi@0.62.0': optional: true @@ -7602,6 +7788,28 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + oxc-transform-react@0.144.0: + optionalDependencies: + '@oxc-transform-react/binding-android-arm-eabi': 0.144.0 + '@oxc-transform-react/binding-android-arm64': 0.144.0 + '@oxc-transform-react/binding-darwin-arm64': 0.144.0 + '@oxc-transform-react/binding-darwin-x64': 0.144.0 + '@oxc-transform-react/binding-freebsd-x64': 0.144.0 + '@oxc-transform-react/binding-linux-arm-gnueabihf': 0.144.0 + '@oxc-transform-react/binding-linux-arm-musleabihf': 0.144.0 + '@oxc-transform-react/binding-linux-arm64-gnu': 0.144.0 + '@oxc-transform-react/binding-linux-arm64-musl': 0.144.0 + '@oxc-transform-react/binding-linux-ppc64-gnu': 0.144.0 + '@oxc-transform-react/binding-linux-riscv64-gnu': 0.144.0 + '@oxc-transform-react/binding-linux-riscv64-musl': 0.144.0 + '@oxc-transform-react/binding-linux-s390x-gnu': 0.144.0 + '@oxc-transform-react/binding-linux-x64-gnu': 0.144.0 + '@oxc-transform-react/binding-linux-x64-musl': 0.144.0 + '@oxc-transform-react/binding-openharmony-arm64': 0.144.0 + '@oxc-transform-react/binding-win32-arm64-msvc': 0.144.0 + '@oxc-transform-react/binding-win32-ia32-msvc': 0.144.0 + '@oxc-transform-react/binding-win32-x64-msvc': 0.144.0 + oxfmt@0.62.0: dependencies: tinypool: 2.1.0