From 846bd094d2d3f9725b2e87e574a70221264f8697 Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Jul 2023 16:33:59 +0800 Subject: [PATCH 1/2] fix(esbuild): enable experimentalDecorators by default --- packages/vite/src/node/plugins/esbuild.ts | 8 ++++++++ .../tsconfig-json/__tests__/tsconfig-json.spec.ts | 12 ++++++++++++ playground/tsconfig-json/src/decorator.ts | 8 ++++++++ 3 files changed, 28 insertions(+) create mode 100644 playground/tsconfig-json/src/decorator.ts diff --git a/packages/vite/src/node/plugins/esbuild.ts b/packages/vite/src/node/plugins/esbuild.ts index fedb39d9d844a1..128d14f6ce1cd0 100644 --- a/packages/vite/src/node/plugins/esbuild.ts +++ b/packages/vite/src/node/plugins/esbuild.ts @@ -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) { diff --git a/playground/tsconfig-json/__tests__/tsconfig-json.spec.ts b/playground/tsconfig-json/__tests__/tsconfig-json.spec.ts index a5e2dd47d191cd..dd130a65291001 100644 --- a/playground/tsconfig-json/__tests__/tsconfig-json.spec.ts +++ b/playground/tsconfig-json/__tests__/tsconfig-json.spec.ts @@ -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') + }) }) diff --git a/playground/tsconfig-json/src/decorator.ts b/playground/tsconfig-json/src/decorator.ts new file mode 100644 index 00000000000000..27a5027cb23f17 --- /dev/null +++ b/playground/tsconfig-json/src/decorator.ts @@ -0,0 +1,8 @@ +function first() { + return function (...args: any[]) {} +} + +export class Foo { + @first() + method() {} +} From cbb24c4ead343583c142ad8a6c806701fcab0e93 Mon Sep 17 00:00:00 2001 From: bluwy Date: Thu, 13 Jul 2023 14:08:34 +0800 Subject: [PATCH 2/2] fix: enable experimentalDecorators during scan --- packages/vite/src/node/optimizer/scan.ts | 17 +++++++++++++++-- playground/tsconfig-json/src/decorator.ts | 5 ++++- playground/tsconfig-json/src/main.ts | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 3c592cec499de5..c762b6b584cf8f 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -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(), @@ -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, }) } diff --git a/playground/tsconfig-json/src/decorator.ts b/playground/tsconfig-json/src/decorator.ts index 27a5027cb23f17..2dc056ec09c809 100644 --- a/playground/tsconfig-json/src/decorator.ts +++ b/playground/tsconfig-json/src/decorator.ts @@ -4,5 +4,8 @@ function first() { export class Foo { @first() - method() {} + // @ts-expect-error we intentionally not enable `experimentalDecorators` to test esbuild compat + method(@first test: string) { + return test + } } diff --git a/playground/tsconfig-json/src/main.ts b/playground/tsconfig-json/src/main.ts index 6ae1fe03b7d023..bec5c6bcc2729d 100644 --- a/playground/tsconfig-json/src/main.ts +++ b/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'