Skip to content

Commit c188ada

Browse files
underfinIWANABETHATGUY
authored andcommitted
feat: oxc tranformer (#60)
Co-authored-by: IWANABETHATGUY <iwanabethatguy@qq.com>
1 parent a438d11 commit c188ada

File tree

10 files changed

+298
-26
lines changed

10 files changed

+298
-26
lines changed

packages/vite/rollup.dts.config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const external = [
1717
/^node:*/,
1818
/^vite\//,
1919
'rollup/parseAst',
20+
'rolldown/experimental',
2021
...Object.keys(pkg.dependencies),
2122
// lightningcss types are bundled
2223
...Object.keys(pkg.devDependencies).filter((d) => d !== 'lightningcss'),
@@ -52,6 +53,9 @@ const identifierReplacements: Record<string, Record<string, string>> = {
5253
TransformPluginContext$1: 'rolldown.TransformPluginContext',
5354
TransformResult$2: 'rolldown.TransformResult',
5455
},
56+
'rolldown/experimental': {
57+
TransformOptions$2: 'rolldown_experimental_TransformOptions',
58+
},
5559
esbuild: {
5660
TransformResult$1: 'esbuild_TransformResult',
5761
TransformOptions$1: 'esbuild_TransformOptions',

packages/vite/src/node/__tests__/plugins/import.spec.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,13 @@ describe('transformCjsImport', () => {
7373
'',
7474
config,
7575
),
76-
).toBe(
77-
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
78-
`const react = ((m) => m?.__esModule ? m : { ...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {}, default: m })(__vite__cjsImport0_react)`,
76+
).toMatchInlineSnapshot(
77+
`
78+
"import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; const react = ((m) => m?.__esModule ? m : {
79+
...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {},
80+
default: m
81+
})(__vite__cjsImport0_react)"
82+
`,
7983
)
8084
})
8185

packages/vite/src/node/config.ts

+29-5
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ import type { ResolvedSSROptions, SSROptions } from './ssr'
8888
import { resolveSSROptions } from './ssr'
8989
import { PartialEnvironment } from './baseEnvironment'
9090
import { createIdResolver } from './idResolver'
91+
import { type OxcOptions, convertEsbuildConfigToOxcConfig } from './plugins/oxc'
9192

9293
const debug = createDebugger('vite:config')
9394
const promisifiedRealpath = promisify(fs.realpath)
@@ -339,6 +340,11 @@ export interface UserConfig extends DefaultEnvironmentOptions {
339340
* Or set to `false` to disable esbuild.
340341
*/
341342
esbuild?: ESBuildOptions | false
343+
/**
344+
* Transform options to pass to esbuild.
345+
* Or set to `false` to disable esbuild.
346+
*/
347+
oxc?: OxcOptions | false
342348
/**
343349
* Specify additional picomatch patterns to be treated as static assets.
344350
*/
@@ -569,7 +575,8 @@ export type ResolvedConfig = Readonly<
569575
}
570576
plugins: readonly Plugin[]
571577
css: ResolvedCSSOptions
572-
esbuild: ESBuildOptions | false
578+
// esbuild: ESBuildOptions | false
579+
oxc: OxcOptions | false
573580
server: ResolvedServerOptions
574581
dev: ResolvedDevEnvironmentOptions
575582
builder: ResolvedBuilderOptions
@@ -1305,6 +1312,18 @@ export async function resolveConfig(
13051312

13061313
const base = withTrailingSlash(resolvedBase)
13071314

1315+
let oxc: OxcOptions | false | undefined = config.oxc
1316+
1317+
if (config.esbuild) {
1318+
if (config.oxc) {
1319+
logger.warn(
1320+
`Found esbuild and oxc options, will use oxc and ignore esbuild at transformer.`,
1321+
)
1322+
} else {
1323+
oxc = convertEsbuildConfigToOxcConfig(config.esbuild, logger)
1324+
}
1325+
}
1326+
13081327
resolved = {
13091328
configFile: configFile ? normalizePath(configFile) : undefined,
13101329
configFileDependencies: configFileDependencies.map((name) =>
@@ -1325,13 +1344,18 @@ export async function resolveConfig(
13251344
isProduction,
13261345
plugins: userPlugins, // placeholder to be replaced
13271346
css: resolveCSSOptions(config.css),
1328-
esbuild:
1329-
config.esbuild === false
1347+
oxc:
1348+
oxc === false
13301349
? false
13311350
: {
1332-
jsxDev: !isProduction,
1333-
...config.esbuild,
1351+
...oxc,
1352+
jsx: {
1353+
development: !isProduction,
1354+
...oxc?.jsx,
1355+
},
13341356
},
1357+
// preserve esbuild for buildEsbuildPlugin
1358+
esbuild: config.esbuild,
13351359
server,
13361360
builder,
13371361
preview: resolvePreviewOptions(config.preview, server),

packages/vite/src/node/optimizer/index.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ import {
2828
unique,
2929
} from '../utils'
3030
import { transformWithEsbuild } from '../plugins/esbuild'
31-
import { ESBUILD_MODULES_TARGET, METADATA_FILENAME } from '../constants'
31+
import { METADATA_FILENAME } from '../constants'
3232
import { isWindows } from '../../shared/utils'
3333
import type { Environment } from '../environment'
34+
import { transformWithOxc } from '../plugins/oxc'
3435
import { ScanEnvironment, scanImports } from './scan'
3536
import { createOptimizeDepsIncludeResolver, expandGlobIds } from './resolve'
3637
import {
@@ -765,12 +766,9 @@ async function prepareRolldownOptimizerRun(
765766
name: 'optimizer-transform',
766767
async transform(code, id) {
767768
if (/\.(?:m?[jt]s|[jt]sx)$/.test(id)) {
768-
const result = await transformWithEsbuild(code, id, {
769+
const result = await transformWithOxc(this, code, id, {
769770
sourcemap: true,
770-
sourcefile: id,
771-
loader: jsxLoader && /\.js$/.test(id) ? 'jsx' : undefined,
772-
define,
773-
target: ESBUILD_MODULES_TARGET,
771+
lang: jsxLoader && /\.js$/.test(id) ? 'jsx' : undefined,
774772
})
775773
return {
776774
code: result.code,
@@ -787,6 +785,7 @@ async function prepareRolldownOptimizerRun(
787785
input: flatIdDeps,
788786
logLevel: 'warn',
789787
plugins,
788+
define,
790789
platform,
791790
resolve: {
792791
// TODO: set aliasFields, conditionNames depending on `platform`

packages/vite/src/node/plugins/esbuild.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ export const defaultEsbuildSupported = {
4343

4444
// TODO: rework to avoid caching the server for this module.
4545
// If two servers are created in the same process, they will interfere with each other.
46-
let server: ViteDevServer
46+
let server: ViteDevServer | null
47+
48+
export function setServer(s: ViteDevServer | null): void {
49+
server = s
50+
}
4751

4852
export interface ESBuildOptions extends TransformOptions {
4953
include?: string | RegExp | string[] | RegExp[]
@@ -253,16 +257,16 @@ export function esbuildPlugin(config: ResolvedConfig): Plugin {
253257

254258
return {
255259
name: 'vite:esbuild',
256-
configureServer(_server) {
257-
server = _server
260+
configureServer(server) {
261+
setServer(server)
258262
server.watcher
259263
.on('add', reloadOnTsconfigChange)
260264
.on('change', reloadOnTsconfigChange)
261265
.on('unlink', reloadOnTsconfigChange)
262266
},
263267
buildEnd() {
264268
// recycle serve to avoid preventing Node self-exit (#6815)
265-
server = null as any
269+
setServer(null)
266270
},
267271
async transform(code, id) {
268272
if (filter(id) || filter(cleanUrl(id))) {
@@ -477,7 +481,9 @@ export async function loadTsconfigJsonForFile(
477481
}
478482
}
479483

480-
async function reloadOnTsconfigChange(changedFile: string) {
484+
export async function reloadOnTsconfigChange(
485+
changedFile: string,
486+
): Promise<void> {
481487
// server could be closed externally after a file change is detected
482488
if (!server) return
483489
// any tsconfig.json that's added in the workspace could be closer to a code file than a previously cached one

packages/vite/src/node/plugins/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { getFsUtils } from '../fsUtils'
1818
import { jsonPlugin } from './json'
1919
import { filteredResolvePlugin, resolvePlugin } from './resolve'
2020
import { optimizedDepsPlugin } from './optimizedDeps'
21-
import { esbuildPlugin } from './esbuild'
2221
import { importAnalysisPlugin } from './importAnalysis'
2322
import { cssAnalysisPlugin, cssPlugin, cssPostPlugin } from './css'
2423
import { assetPlugin } from './asset'
@@ -34,6 +33,7 @@ import { assetImportMetaUrlPlugin } from './assetImportMetaUrl'
3433
import { metadataPlugin } from './metadata'
3534
import { dynamicImportVarsPlugin } from './dynamicImportVars'
3635
import { importGlobPlugin } from './importMetaGlob'
36+
import { oxcPlugin } from './oxc'
3737

3838
export async function resolvePlugins(
3939
config: ResolvedConfig,
@@ -111,10 +111,10 @@ export async function resolvePlugins(
111111
),
112112
htmlInlineProxyPlugin(config),
113113
cssPlugin(config),
114-
config.esbuild !== false
114+
config.oxc !== false
115115
? enableNativePlugin
116116
? nativeTransformPlugin()
117-
: esbuildPlugin(config)
117+
: oxcPlugin(config)
118118
: null,
119119
enableNativePlugin
120120
? nativeJsonPlugin({

0 commit comments

Comments
 (0)