Skip to content

Commit e8880f0

Browse files
authored
fix(esbuild): enable experimentalDecorators by default (#13805)
1 parent 85bdcda commit e8880f0

File tree

5 files changed

+47
-2
lines changed

5 files changed

+47
-2
lines changed

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

+15-2
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,11 @@ async function prepareEsbuildScanner(
205205

206206
const plugin = esbuildScanPlugin(config, container, deps, missing, entries)
207207

208-
const { plugins = [], ...esbuildOptions } =
209-
config.optimizeDeps?.esbuildOptions ?? {}
208+
const {
209+
plugins = [],
210+
tsconfigRaw,
211+
...esbuildOptions
212+
} = config.optimizeDeps?.esbuildOptions ?? {}
210213

211214
return await esbuild.context({
212215
absWorkingDir: process.cwd(),
@@ -219,6 +222,16 @@ async function prepareEsbuildScanner(
219222
format: 'esm',
220223
logLevel: 'silent',
221224
plugins: [...plugins, plugin],
225+
tsconfigRaw:
226+
typeof tsconfigRaw === 'string'
227+
? tsconfigRaw
228+
: {
229+
...tsconfigRaw,
230+
compilerOptions: {
231+
experimentalDecorators: true,
232+
...tsconfigRaw?.compilerOptions,
233+
},
234+
},
222235
...esbuildOptions,
223236
})
224237
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ export async function transformWithEsbuild(
142142
compilerOptions.useDefineForClassFields = false
143143
}
144144

145+
// esbuild v0.18 only transforms decorators when `experimentalDecorators` is set to `true`.
146+
// To preserve compat with the esbuild breaking change, we set `experimentalDecorators` to
147+
// `true` by default if it's unset.
148+
// TODO: Remove this in Vite 5
149+
if (compilerOptions.experimentalDecorators === undefined) {
150+
compilerOptions.experimentalDecorators = true
151+
}
152+
145153
// esbuild uses tsconfig fields when both the normal options and tsconfig was set
146154
// but we want to prioritize the normal options
147155
if (options) {

playground/tsconfig-json/__tests__/tsconfig-json.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,16 @@ describe('transformWithEsbuild', () => {
6767
'import { MainTypeOnlyClass } from "./not-used-type";',
6868
)
6969
})
70+
71+
test('experimentalDecorators', async () => {
72+
const main = path.resolve(__dirname, '../src/decorator.ts')
73+
const mainContent = fs.readFileSync(main, 'utf-8')
74+
// Should not error when transpiling decorators
75+
// TODO: In Vite 5, this should require setting `tsconfigRaw.experimentalDecorators`
76+
// or via the closest `tsconfig.json`
77+
const result = await transformWithEsbuild(mainContent, main, {
78+
target: 'es2020',
79+
})
80+
expect(result.code).toContain('__decorateClass')
81+
})
7082
})
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function first() {
2+
return function (...args: any[]) {}
3+
}
4+
5+
export class Foo {
6+
@first()
7+
// @ts-expect-error we intentionally not enable `experimentalDecorators` to test esbuild compat
8+
method(@first test: string) {
9+
return test
10+
}
11+
}

playground/tsconfig-json/src/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @ts-nocheck
22
import '../nested/main'
33
import '../nested-with-extends/main'
4+
import './decorator'
45

56
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
67
import { MainTypeOnlyClass } from './not-used-type'

0 commit comments

Comments
 (0)