Skip to content

Commit

Permalink
fix(esbuild): enable experimentalDecorators by default (#13805)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Jul 13, 2023
1 parent 85bdcda commit e8880f0
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
17 changes: 15 additions & 2 deletions packages/vite/src/node/optimizer/scan.ts
Expand Up @@ -205,8 +205,11 @@ async function prepareEsbuildScanner(

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

const { plugins = [], ...esbuildOptions } =
config.optimizeDeps?.esbuildOptions ?? {}
const {
plugins = [],
tsconfigRaw,
...esbuildOptions
} = config.optimizeDeps?.esbuildOptions ?? {}

return await esbuild.context({
absWorkingDir: process.cwd(),
Expand All @@ -219,6 +222,16 @@ async function prepareEsbuildScanner(
format: 'esm',
logLevel: 'silent',
plugins: [...plugins, plugin],
tsconfigRaw:
typeof tsconfigRaw === 'string'
? tsconfigRaw
: {
...tsconfigRaw,
compilerOptions: {
experimentalDecorators: true,
...tsconfigRaw?.compilerOptions,
},
},
...esbuildOptions,
})
}
Expand Down
8 changes: 8 additions & 0 deletions packages/vite/src/node/plugins/esbuild.ts
Expand Up @@ -142,6 +142,14 @@ export async function transformWithEsbuild(
compilerOptions.useDefineForClassFields = false
}

// esbuild v0.18 only transforms decorators when `experimentalDecorators` is set to `true`.
// To preserve compat with the esbuild breaking change, we set `experimentalDecorators` to
// `true` by default if it's unset.
// TODO: Remove this in Vite 5
if (compilerOptions.experimentalDecorators === undefined) {
compilerOptions.experimentalDecorators = true
}

// esbuild uses tsconfig fields when both the normal options and tsconfig was set
// but we want to prioritize the normal options
if (options) {
Expand Down
12 changes: 12 additions & 0 deletions playground/tsconfig-json/__tests__/tsconfig-json.spec.ts
Expand Up @@ -67,4 +67,16 @@ describe('transformWithEsbuild', () => {
'import { MainTypeOnlyClass } from "./not-used-type";',
)
})

test('experimentalDecorators', async () => {
const main = path.resolve(__dirname, '../src/decorator.ts')
const mainContent = fs.readFileSync(main, 'utf-8')
// Should not error when transpiling decorators
// TODO: In Vite 5, this should require setting `tsconfigRaw.experimentalDecorators`
// or via the closest `tsconfig.json`
const result = await transformWithEsbuild(mainContent, main, {
target: 'es2020',
})
expect(result.code).toContain('__decorateClass')
})
})
11 changes: 11 additions & 0 deletions playground/tsconfig-json/src/decorator.ts
@@ -0,0 +1,11 @@
function first() {
return function (...args: any[]) {}
}

export class Foo {
@first()
// @ts-expect-error we intentionally not enable `experimentalDecorators` to test esbuild compat
method(@first test: string) {
return test
}
}
1 change: 1 addition & 0 deletions playground/tsconfig-json/src/main.ts
@@ -1,6 +1,7 @@
// @ts-nocheck
import '../nested/main'
import '../nested-with-extends/main'
import './decorator'

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

0 comments on commit e8880f0

Please sign in to comment.