Skip to content

Commit f677b62

Browse files
authored
feat!: transform jsx with esbuild instead of babel (#9590)
1 parent ff3eacf commit f677b62

File tree

8 files changed

+96
-949
lines changed

8 files changed

+96
-949
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"@typescript-eslint/eslint-plugin": "^5.42.0",
6262
"@typescript-eslint/parser": "^5.42.0",
6363
"conventional-changelog-cli": "^2.2.2",
64-
"esbuild": "^0.14.47",
64+
"esbuild": "^0.15.9",
6565
"eslint": "^8.27.0",
6666
"eslint-define-config": "^1.11.0",
6767
"eslint-plugin-import": "^2.26.0",

packages/plugin-react/src/index.ts

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import path from 'node:path'
21
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
32
import * as babel from '@babel/core'
4-
import { createFilter, normalizePath } from 'vite'
3+
import { createFilter } from 'vite'
54
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
65
import MagicString from 'magic-string'
76
import type { SourceMap } from 'magic-string'
@@ -12,8 +11,6 @@ import {
1211
runtimeCode,
1312
runtimePublicPath
1413
} from './fast-refresh'
15-
import { babelImportToRequire } from './jsx-runtime/babel-import-to-require'
16-
import { restoreJSX } from './jsx-runtime/restore-jsx'
1714

1815
export interface Options {
1916
include?: string | RegExp | Array<string | RegExp>
@@ -40,11 +37,6 @@ export interface Options {
4037
* @default true
4138
*/
4239
jsxPure?: boolean
43-
/**
44-
* Toggles whether or not to throw an error if an XML namespaced tag name is used.
45-
* @default true
46-
*/
47-
jsxThrowIfNamespace?: boolean
4840
/**
4941
* Babel configuration applied in both dev and prod.
5042
*/
@@ -100,7 +92,6 @@ const prependReactImportCode = "import React from 'react'; "
10092
export default function viteReact(opts: Options = {}): PluginOption[] {
10193
// Provide default values for Rollup compat.
10294
let devBase = '/'
103-
let resolvedCacheDir: string
10495
let filter = createFilter(opts.include, opts.exclude)
10596
let needHiresSourcemap = false
10697
let isProduction = true
@@ -127,21 +118,37 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
127118
const viteBabel: Plugin = {
128119
name: 'vite:react-babel',
129120
enforce: 'pre',
130-
config() {
121+
config(_, { mode }) {
122+
// Copied from https://github.com/vitejs/vite/blob/4e9bdd4fb3654a9d43917e1cb682d3d2bad25115/packages/vite/src/node/config.ts#L488-L490
123+
const isProduction =
124+
(process.env.NODE_ENV || process.env.VITE_USER_NODE_ENV || mode) ===
125+
'production'
126+
131127
if (opts.jsxRuntime === 'classic') {
132128
return {
133129
esbuild: {
134130
logOverride: {
135131
'this-is-undefined-in-esm': 'silent'
136-
}
132+
},
133+
jsx: 'transform',
134+
jsxImportSource: opts.jsxImportSource,
135+
jsxSideEffects: opts.jsxPure === false
136+
}
137+
}
138+
} else {
139+
return {
140+
esbuild: {
141+
jsxDev: !isProduction,
142+
jsx: 'automatic',
143+
jsxImportSource: opts.jsxImportSource,
144+
jsxSideEffects: opts.jsxPure === false
137145
}
138146
}
139147
}
140148
},
141149
configResolved(config) {
142150
devBase = config.base
143151
projectRoot = config.root
144-
resolvedCacheDir = normalizePath(path.resolve(config.cacheDir))
145152
filter = createFilter(opts.include, opts.exclude, {
146153
resolve: projectRoot
147154
})
@@ -231,39 +238,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
231238
let ast: t.File | null | undefined
232239
let prependReactImport = false
233240
if (!isProjectFile || isJSX) {
234-
if (useAutomaticRuntime) {
235-
// By reverse-compiling "React.createElement" calls into JSX,
236-
// React elements provided by dependencies will also use the
237-
// automatic runtime!
238-
// Avoid parsing the optimized react-dom since it will never
239-
// contain compiled JSX and it's a pretty big file (800kb).
240-
const isOptimizedReactDom =
241-
id.startsWith(resolvedCacheDir) && id.includes('/react-dom.js')
242-
const [restoredAst, isCommonJS] =
243-
!isProjectFile && !isJSX && !isOptimizedReactDom
244-
? await restoreJSX(babel, code, id)
245-
: [null, false]
246-
247-
if (isJSX || (ast = restoredAst)) {
248-
plugins.push([
249-
await loadPlugin(
250-
'@babel/plugin-transform-react-jsx' +
251-
(isProduction ? '' : '-development')
252-
),
253-
{
254-
runtime: 'automatic',
255-
importSource: opts.jsxImportSource,
256-
pure: opts.jsxPure !== false,
257-
throwIfNamespace: opts.jsxThrowIfNamespace
258-
}
259-
])
260-
261-
// Avoid inserting `import` statements into CJS modules.
262-
if (isCommonJS) {
263-
plugins.push(babelImportToRequire)
264-
}
265-
}
266-
} else if (isProjectFile) {
241+
if (!useAutomaticRuntime && isProjectFile) {
267242
// These plugins are only needed for the classic runtime.
268243
if (!isProduction) {
269244
plugins.push(

packages/plugin-react/src/jsx-runtime/babel-import-to-require.ts

Lines changed: 0 additions & 35 deletions
This file was deleted.

packages/plugin-react/src/jsx-runtime/babel-restore-jsx.spec.ts

Lines changed: 0 additions & 132 deletions
This file was deleted.

0 commit comments

Comments
 (0)