From cefcef94efda9f8c296a0684227087bd9365ca26 Mon Sep 17 00:00:00 2001 From: natew Date: Sun, 9 Feb 2025 08:42:14 -1000 Subject: [PATCH] move to oxc and use babel for classes --- packages/compiler/package.json | 3 + packages/compiler/src/constants.ts | 2 + packages/compiler/src/transformBabel.ts | 7 +- packages/compiler/src/transformSWC.ts | 184 ++++++++++++------------ packages/compiler/types/constants.d.ts | 1 + yarn.lock | 92 ++++++++++++ 6 files changed, 200 insertions(+), 89 deletions(-) diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 0e1df1d1c..d2e0413fd 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -29,6 +29,8 @@ }, "dependencies": { "@babel/core": "^7.26.0", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", "@babel/plugin-transform-react-jsx": "^7.25.9", @@ -37,6 +39,7 @@ "@vxrn/utils": "workspace:*", "@vxrn/vite-native-client": "workspace:*", "babel-plugin-react-compiler": "^19.0.0-beta-201e55d-20241215", + "oxc-transform": "^0.48.2", "react-native-css-interop": "^0.1.22", "ts-deepmerge": "^7.0.2", "vite": "^6.1.0" diff --git a/packages/compiler/src/constants.ts b/packages/compiler/src/constants.ts index 1837efe38..3764a157f 100644 --- a/packages/compiler/src/constants.ts +++ b/packages/compiler/src/constants.ts @@ -19,3 +19,5 @@ export const parsers: Record = { } export const validParsers = new Set([...Object.keys(parsers), '.css']) + +export const USE_OXC = false diff --git a/packages/compiler/src/transformBabel.ts b/packages/compiler/src/transformBabel.ts index e4475dfa3..ca0c9d2e7 100644 --- a/packages/compiler/src/transformBabel.ts +++ b/packages/compiler/src/transformBabel.ts @@ -2,7 +2,7 @@ import babel from '@babel/core' import { resolvePath } from '@vxrn/utils' import { relative } from 'node:path' import { configuration } from './configure' -import { asyncGeneratorRegex, debug } from './constants' +import { asyncGeneratorRegex, debug, USE_OXC } from './constants' import type { GetTransformProps, GetTransformResponse } from './types' type Props = GetTransformProps & { @@ -52,6 +52,11 @@ const getOptions = (props: Props, force = false): babel.TransformOptions | null plugins.push('react-native-reanimated/plugin') } + if (USE_OXC && /class [a-z]+ \{/i.test(props.code)) { + plugins.push(`@babel/plugin-transform-class-properties`) + plugins.push(`@babel/plugin-transform-classes`) + } + if (shouldBabelReactCompiler(props)) { debug?.(`Using babel react compiler on file`) plugins.push(getBabelReactCompilerPlugin(props)) diff --git a/packages/compiler/src/transformSWC.ts b/packages/compiler/src/transformSWC.ts index 07c1cfd28..2c34e88cf 100644 --- a/packages/compiler/src/transformSWC.ts +++ b/packages/compiler/src/transformSWC.ts @@ -8,7 +8,7 @@ import { import { extname, sep } from 'node:path' import { merge } from 'ts-deepmerge' import { configuration } from './configure' -import { asyncGeneratorRegex, debug, parsers, runtimePublicPath } from './constants' +import { asyncGeneratorRegex, debug, parsers, runtimePublicPath, USE_OXC } from './constants' import type { Options } from './types' const ignoreId = new RegExp(`node_modules\\${sep}(\\.vite|vite)\\${sep}`) @@ -45,108 +45,116 @@ export async function transformSWC( !options.forceJSX && !id.includes('node_modules') - const reactConfig = { - refresh, - development: !options.forceJSX && !options.production, - runtime: 'automatic', - importSource: 'react', - ...(configuration.enableNativewind && !id.includes('node_modules') - ? { - importSource: 'nativewind', - // pragma: 'createInteropElement', - // pragmaFrag: '_InteropFragment', - // swc doesnt actually change the import right - // runtime: 'classic', - } - : {}), - } satisfies TransformConfig['react'] - - const transformOptions = ((): SWCOptions => { - if (options.environment === 'client' || options.environment === 'ssr') { - return { - sourceMaps: shouldSourceMap(), - jsc: { - target: 'es2020', - parser, - transform: { - useDefineForClassFields: true, - react: reactConfig, - }, - }, - } - } - - const shouldEs5Transform = - options.es5 || (!process.env.VXRN_USE_BABEL_FOR_GENERATORS && asyncGeneratorRegex.test(code)) - - const opts: SWCOptions = shouldEs5Transform - ? { + let result: Output + + if (USE_OXC) { + const oxc = await import('oxc-transform') + result = oxc.transform(id, code, {}) + } else { + const reactConfig = { + refresh, + development: !options.forceJSX && !options.production, + runtime: 'automatic', + importSource: 'react', + ...(configuration.enableNativewind && !id.includes('node_modules') + ? { + importSource: 'nativewind', + // pragma: 'createInteropElement', + // pragmaFrag: '_InteropFragment', + // swc doesnt actually change the import right + // runtime: 'classic', + } + : {}), + } satisfies TransformConfig['react'] + + const transformOptions = ((): SWCOptions => { + if (options.environment === 'client' || options.environment === 'ssr') { + return { + sourceMaps: shouldSourceMap(), jsc: { + target: 'es2020', parser, - target: 'es5', transform: { useDefineForClassFields: true, react: reactConfig, }, }, } - : { - ...(!options.forceJSX && { env: SWC_ENV }), - jsc: { - ...(options.forceJSX && { target: 'esnext' }), - parser, - transform: { - useDefineForClassFields: true, - react: reactConfig, + } + + const shouldEs5Transform = + options.es5 || + (!process.env.VXRN_USE_BABEL_FOR_GENERATORS && asyncGeneratorRegex.test(code)) + + const opts: SWCOptions = shouldEs5Transform + ? { + jsc: { + parser, + target: 'es5', + transform: { + useDefineForClassFields: true, + react: reactConfig, + }, }, - }, - } + } + : { + ...(!options.forceJSX && { env: SWC_ENV }), + jsc: { + ...(options.forceJSX && { target: 'esnext' }), + parser, + transform: { + useDefineForClassFields: true, + react: reactConfig, + }, + }, + } - return { - sourceMaps: shouldSourceMap(), - module: { - importInterop: 'none', - type: 'nodenext', - }, - ...(options.mode === 'serve-cjs' && { + return { + sourceMaps: shouldSourceMap(), module: { importInterop: 'none', - type: 'commonjs', - strict: true, + type: 'nodenext', }, - }), - ...opts, - } - })() - - const finalOptions = merge( - { - filename: id, - swcrc: false, - configFile: false, - ...transformOptions, - }, - swcOptions || {} - ) satisfies SWCOptions - - const result: Output = await (async () => { - try { - debug?.(`transformSWC ${id} using options:\n${JSON.stringify(finalOptions, null, 2)}`) - - return await transform(code, finalOptions) - } catch (e: any) { - const message: string = e.message - const fileStartIndex = message.indexOf('╭─[') - if (fileStartIndex !== -1) { - const match = message.slice(fileStartIndex).match(/:(\d+):(\d+)]/) - if (match) { - e.line = match[1] - e.column = match[2] + ...(options.mode === 'serve-cjs' && { + module: { + importInterop: 'none', + type: 'commonjs', + strict: true, + }, + }), + ...opts, + } + })() + + const finalOptions = merge( + { + filename: id, + swcrc: false, + configFile: false, + ...transformOptions, + }, + swcOptions || {} + ) satisfies SWCOptions + + result = await (async () => { + try { + debug?.(`transformSWC ${id} using options:\n${JSON.stringify(finalOptions, null, 2)}`) + + return await transform(code, finalOptions) + } catch (e: any) { + const message: string = e.message + const fileStartIndex = message.indexOf('╭─[') + if (fileStartIndex !== -1) { + const match = message.slice(fileStartIndex).match(/:(\d+):(\d+)]/) + if (match) { + e.line = match[1] + e.column = match[2] + } } + throw e } - throw e - } - })() + })() + } if (configuration.enableNativeCSS) { if (result.code.includes(`createInteropElement(`)) { diff --git a/packages/compiler/types/constants.d.ts b/packages/compiler/types/constants.d.ts index 53118da55..36dea2dfc 100644 --- a/packages/compiler/types/constants.d.ts +++ b/packages/compiler/types/constants.d.ts @@ -6,4 +6,5 @@ export declare const runtimePublicPath = "/@react-refresh"; export declare const asyncGeneratorRegex: RegExp; export declare const parsers: Record; export declare const validParsers: Set; +export declare const USE_OXC = false; //# sourceMappingURL=constants.d.ts.map \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 10753da51..717948291 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6194,6 +6194,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-darwin-arm64@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-darwin-arm64@npm:0.48.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@oxc-transform/binding-darwin-x64@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-darwin-x64@npm:0.47.1" @@ -6201,6 +6208,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-darwin-x64@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-darwin-x64@npm:0.48.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@oxc-transform/binding-linux-arm64-gnu@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-linux-arm64-gnu@npm:0.47.1" @@ -6208,6 +6222,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-linux-arm64-gnu@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-linux-arm64-gnu@npm:0.48.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@oxc-transform/binding-linux-arm64-musl@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-linux-arm64-musl@npm:0.47.1" @@ -6215,6 +6236,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-linux-arm64-musl@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-linux-arm64-musl@npm:0.48.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@oxc-transform/binding-linux-x64-gnu@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-linux-x64-gnu@npm:0.47.1" @@ -6222,6 +6250,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-linux-x64-gnu@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-linux-x64-gnu@npm:0.48.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@oxc-transform/binding-linux-x64-musl@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-linux-x64-musl@npm:0.47.1" @@ -6229,6 +6264,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-linux-x64-musl@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-linux-x64-musl@npm:0.48.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@oxc-transform/binding-win32-arm64-msvc@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-win32-arm64-msvc@npm:0.47.1" @@ -6236,6 +6278,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-win32-arm64-msvc@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-win32-arm64-msvc@npm:0.48.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@oxc-transform/binding-win32-x64-msvc@npm:0.47.1": version: 0.47.1 resolution: "@oxc-transform/binding-win32-x64-msvc@npm:0.47.1" @@ -6243,6 +6292,13 @@ __metadata: languageName: node linkType: hard +"@oxc-transform/binding-win32-x64-msvc@npm:0.48.2": + version: 0.48.2 + resolution: "@oxc-transform/binding-win32-x64-msvc@npm:0.48.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@peculiar/asn1-android@npm:^2.3.10": version: 2.3.13 resolution: "@peculiar/asn1-android@npm:2.3.13" @@ -11380,6 +11436,8 @@ __metadata: resolution: "@vxrn/compiler@workspace:packages/compiler" dependencies: "@babel/core": "npm:^7.26.0" + "@babel/plugin-transform-class-properties": "npm:^7.25.9" + "@babel/plugin-transform-classes": "npm:^7.25.9" "@babel/plugin-transform-destructuring": "npm:^7.25.9" "@babel/plugin-transform-private-methods": "npm:^7.25.9" "@babel/plugin-transform-react-jsx": "npm:^7.25.9" @@ -11390,6 +11448,7 @@ __metadata: "@vxrn/vite-native-client": "workspace:*" babel-plugin-react-compiler: "npm:^19.0.0-beta-201e55d-20241215" depcheck: "npm:^1.4.7" + oxc-transform: "npm:^0.48.2" react-native: "npm:^0.76.5" react-native-css-interop: "npm:^0.1.22" rollup: "npm:^4.29.1" @@ -22450,6 +22509,39 @@ __metadata: languageName: node linkType: hard +"oxc-transform@npm:^0.48.2": + version: 0.48.2 + resolution: "oxc-transform@npm:0.48.2" + dependencies: + "@oxc-transform/binding-darwin-arm64": "npm:0.48.2" + "@oxc-transform/binding-darwin-x64": "npm:0.48.2" + "@oxc-transform/binding-linux-arm64-gnu": "npm:0.48.2" + "@oxc-transform/binding-linux-arm64-musl": "npm:0.48.2" + "@oxc-transform/binding-linux-x64-gnu": "npm:0.48.2" + "@oxc-transform/binding-linux-x64-musl": "npm:0.48.2" + "@oxc-transform/binding-win32-arm64-msvc": "npm:0.48.2" + "@oxc-transform/binding-win32-x64-msvc": "npm:0.48.2" + dependenciesMeta: + "@oxc-transform/binding-darwin-arm64": + optional: true + "@oxc-transform/binding-darwin-x64": + optional: true + "@oxc-transform/binding-linux-arm64-gnu": + optional: true + "@oxc-transform/binding-linux-arm64-musl": + optional: true + "@oxc-transform/binding-linux-x64-gnu": + optional: true + "@oxc-transform/binding-linux-x64-musl": + optional: true + "@oxc-transform/binding-win32-arm64-msvc": + optional: true + "@oxc-transform/binding-win32-x64-msvc": + optional: true + checksum: 10/0ae4074c40a2141b4ca935cdd3bd0cd953f8e11a22985b9a4a5b0fcfeec1e21ef30449ea765cccb1aa301bd3683256e529457f48a5bc51c2cd01aacaccbaf344 + languageName: node + linkType: hard + "p-cancelable@npm:^1.0.0": version: 1.1.0 resolution: "p-cancelable@npm:1.1.0"