From 043b0b33e6a9997dcb29e87f988fa053f003816a Mon Sep 17 00:00:00 2001 From: madeofsun Date: Wed, 2 Jul 2025 01:11:31 +0300 Subject: [PATCH 1/9] feat(vue-jsx): allow esbuild to perform ts transformation --- packages/plugin-vue-jsx/README.md | 28 +++++++++++ packages/plugin-vue-jsx/package.json | 1 + packages/plugin-vue-jsx/src/index.ts | 46 ++++++++++++++----- packages/plugin-vue-jsx/src/types.ts | 2 + .../__tests__/vue-jsx-ts-built-in.spec.ts | 32 +++++++++++++ .../decorators-legacy/DecoratorsTs.ts | 36 +++++++++++++++ .../decorators-legacy/DecoratorsTsx.tsx | 32 +++++++++++++ .../decorators-legacy/DecoratorsVueTs.vue | 41 +++++++++++++++++ .../decorators-legacy/DecoratorsVueTsx.vue | 37 +++++++++++++++ .../decorators-legacy/tsconfig.json | 7 +++ .../decorators/DecoratorsTs.ts | 31 +++++++++++++ .../decorators/DecoratorsTsx.tsx | 27 +++++++++++ .../decorators/DecoratorsVueTs.vue | 36 +++++++++++++++ .../decorators/DecoratorsVueTsx.vue | 32 +++++++++++++ .../decorators/tsconfig.json | 7 +++ playground/vue-jsx-ts-built-in/index.html | 2 + playground/vue-jsx-ts-built-in/main.jsx | 26 +++++++++++ playground/vue-jsx-ts-built-in/package.json | 20 ++++++++ playground/vue-jsx-ts-built-in/tsconfig.json | 6 +++ playground/vue-jsx-ts-built-in/vite.config.js | 46 +++++++++++++++++++ pnpm-lock.yaml | 34 +++++++++++++- 21 files changed, 516 insertions(+), 13 deletions(-) create mode 100644 playground/vue-jsx-ts-built-in/__tests__/vue-jsx-ts-built-in.spec.ts create mode 100644 playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts create mode 100644 playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx create mode 100644 playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTs.vue create mode 100644 playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTsx.vue create mode 100644 playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json create mode 100644 playground/vue-jsx-ts-built-in/decorators/DecoratorsTs.ts create mode 100644 playground/vue-jsx-ts-built-in/decorators/DecoratorsTsx.tsx create mode 100644 playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTs.vue create mode 100644 playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTsx.vue create mode 100644 playground/vue-jsx-ts-built-in/decorators/tsconfig.json create mode 100644 playground/vue-jsx-ts-built-in/index.html create mode 100644 playground/vue-jsx-ts-built-in/main.jsx create mode 100644 playground/vue-jsx-ts-built-in/package.json create mode 100644 playground/vue-jsx-ts-built-in/tsconfig.json create mode 100644 playground/vue-jsx-ts-built-in/vite.config.js diff --git a/packages/plugin-vue-jsx/README.md b/packages/plugin-vue-jsx/README.md index 3fd94da9..c97c3296 100644 --- a/packages/plugin-vue-jsx/README.md +++ b/packages/plugin-vue-jsx/README.md @@ -43,6 +43,34 @@ Default: `['defineComponent']` The name of the function to be used for defining components. This is useful when you have a custom `defineComponent` function. +### tsTransform + +Type: `'babel' | 'built-in'` + +Default: `'babel'` + +Defines how `typescript` transformation is handled for `.tsx` files. + +`'babel'` - `typescript` transformation is handled by `@babel/plugin-transform-typescript` during `babel` invocation for JSX transformation. + +`'built-in'` - `babel` is invoked only for JSX transformation and then `typescript` transformation is handled by the same toolchain used for `.ts` files (currently `esbuild`). + +### babelPlugins + +Type: `any[]` + +Default: `undefined` + +Provide additional plugins for `babel` invocation for JSX transformation. + +### tsPluginOptions + +Type: `any` + +Default: `undefined` + +Defines options for `@babel/plugin-transform-typescript` plugin. + ## HMR Detection This plugin supports HMR of Vue JSX components. The detection requirements are: diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json index 832a540f..43d161bc 100644 --- a/packages/plugin-vue-jsx/package.json +++ b/packages/plugin-vue-jsx/package.json @@ -36,6 +36,7 @@ "homepage": "https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx#readme", "dependencies": { "@babel/core": "^7.27.7", + "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1", "@rolldown/pluginutils": "^1.0.0-beta.21", "@vue/babel-plugin-jsx": "^1.4.0" diff --git a/packages/plugin-vue-jsx/src/index.ts b/packages/plugin-vue-jsx/src/index.ts index 0ca5cebe..817d029a 100644 --- a/packages/plugin-vue-jsx/src/index.ts +++ b/packages/plugin-vue-jsx/src/index.ts @@ -49,6 +49,7 @@ function vueJsxPlugin(options: Options = {}): Plugin { babelPlugins = [], defineComponentName = ['defineComponent'], tsPluginOptions = {}, + tsTransform, ...babelPluginOptions } = options const filter = createFilter(include, exclude) @@ -67,9 +68,17 @@ function vueJsxPlugin(options: Options = {}): Plugin { return { // only apply esbuild to ts files // since we are handling jsx and tsx now - esbuild: { - include: /\.ts$/, - }, + esbuild: + tsTransform === 'built-in' + ? { + // For 'built-in' we still need esbuild to transform ts syntax for `.tsx` files. + // So we add `.jsx` extension to `exclude` and keep original `include`. + // https://github.com/vitejs/vite/blob/v6.3.5/packages/vite/src/node/plugins/esbuild.ts#L246 + exclude: /\.jsx?$/, + } + : { + include: /\.ts$/, + }, define: { __VUE_OPTIONS_API__: parseDefine(config.define?.__VUE_OPTIONS_API__) ?? true, @@ -108,6 +117,9 @@ function vueJsxPlugin(options: Options = {}): Plugin { }, transform: { + // Use 'pre' stage for 'built-in' + // to run jsx transformation before esbuild transformation. + order: tsTransform === 'built-in' ? 'pre' : undefined, filter: { id: { include: include ? makeIdFiltersToMatchWithQuery(include) : undefined, @@ -123,14 +135,26 @@ function vueJsxPlugin(options: Options = {}): Plugin { if (filter(id) || filter(filepath)) { const plugins = [[jsx, babelPluginOptions], ...babelPlugins] if (id.endsWith('.tsx') || filepath.endsWith('.tsx')) { - plugins.push([ - // @ts-ignore missing type - await import('@babel/plugin-transform-typescript').then( - (r) => r.default, - ), - // @ts-ignore - { ...tsPluginOptions, isTSX: true, allowExtensions: true }, - ]) + if (tsTransform === 'built-in') { + // For 'built-in' add "syntax" plugin + // to enable parsing without transformation. + plugins.push([ + // @ts-ignore missing type + await import('@babel/plugin-syntax-typescript').then( + (r) => r.default, + ), + { isTSX: true }, + ]) + } else { + plugins.push([ + // @ts-ignore missing type + await import('@babel/plugin-transform-typescript').then( + (r) => r.default, + ), + // @ts-ignore + { ...tsPluginOptions, isTSX: true, allowExtensions: true }, + ]) + } } if (!ssr && !needHmr) { diff --git a/packages/plugin-vue-jsx/src/types.ts b/packages/plugin-vue-jsx/src/types.ts index 0b9f4783..cd7b0de0 100644 --- a/packages/plugin-vue-jsx/src/types.ts +++ b/packages/plugin-vue-jsx/src/types.ts @@ -11,4 +11,6 @@ export interface Options extends VueJSXPluginOptions, FilterOptions { /** @default ['defineComponent'] */ defineComponentName?: string[] tsPluginOptions?: any + /** @default 'babel' */ + tsTransform?: 'babel' | 'built-in' } diff --git a/playground/vue-jsx-ts-built-in/__tests__/vue-jsx-ts-built-in.spec.ts b/playground/vue-jsx-ts-built-in/__tests__/vue-jsx-ts-built-in.spec.ts new file mode 100644 index 00000000..79005d7c --- /dev/null +++ b/playground/vue-jsx-ts-built-in/__tests__/vue-jsx-ts-built-in.spec.ts @@ -0,0 +1,32 @@ +import { expect, test } from 'vitest' +import { page } from '~utils' + +test('should render', async () => { + expect(await page.textContent('.decorators-ts')).toMatch('1') + expect(await page.textContent('.decorators-tsx')).toMatch('2') + expect(await page.textContent('.decorators-vue-ts')).toMatch('3') + expect(await page.textContent('.decorators-vue-tsx')).toMatch('4') + expect(await page.textContent('.decorators-legacy-ts')).toMatch('5') + expect(await page.textContent('.decorators-legacy-tsx')).toMatch('6') + expect(await page.textContent('.decorators-legacy-vue-ts')).toMatch('7') + expect(await page.textContent('.decorators-legacy-vue-tsx')).toMatch('8') +}) + +test('should update', async () => { + await page.click('.decorators-ts') + expect(await page.textContent('.decorators-ts')).toMatch('2') + await page.click('.decorators-tsx') + expect(await page.textContent('.decorators-tsx')).toMatch('3') + await page.click('.decorators-vue-ts') + expect(await page.textContent('.decorators-vue-ts')).toMatch('4') + await page.click('.decorators-vue-tsx') + expect(await page.textContent('.decorators-vue-tsx')).toMatch('5') + await page.click('.decorators-legacy-ts') + expect(await page.textContent('.decorators-legacy-ts')).toMatch('6') + await page.click('.decorators-legacy-tsx') + expect(await page.textContent('.decorators-legacy-tsx')).toMatch('7') + await page.click('.decorators-legacy-vue-ts') + expect(await page.textContent('.decorators-legacy-vue-ts')).toMatch('8') + await page.click('.decorators-legacy-vue-tsx') + expect(await page.textContent('.decorators-legacy-vue-tsx')).toMatch('9') +}) diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts new file mode 100644 index 00000000..b1d62170 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts @@ -0,0 +1,36 @@ +import { defineComponent, h, ref } from 'vue' + +function methodDecorator( + target: unknown, + propertyKey: string, + descriptor: PropertyDescriptor, +) { + const originalMethod = descriptor.value + descriptor.value = function () { + const result = originalMethod.call(this) + this.value.value += 1 + return result + } +} + +export default defineComponent(() => { + class Counter { + value = ref(5) + + @methodDecorator + increment() {} + } + + const counter = new Counter() + const inc = () => counter.increment() + + return () => + h( + 'button', + { + class: 'decorators-legacy-ts', + onClick: inc, + }, + `decorators legacy ts ${counter.value.value}`, + ) +}) diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx new file mode 100644 index 00000000..c1366d94 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx @@ -0,0 +1,32 @@ +import { defineComponent, ref } from 'vue' + +function methodDecorator( + target: unknown, + propertyKey: string, + descriptor: PropertyDescriptor, +) { + const originalMethod = descriptor.value + descriptor.value = function () { + const result = originalMethod.call(this) + this.value.value += 1 + return result + } +} + +export default defineComponent(() => { + class Counter { + value = ref(6) + + @methodDecorator + increment() {} + } + + const counter = new Counter() + const inc = () => counter.increment() + + return () => ( + + ) +}) diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTs.vue b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTs.vue new file mode 100644 index 00000000..a0ee2386 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTs.vue @@ -0,0 +1,41 @@ + + diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTsx.vue b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTsx.vue new file mode 100644 index 00000000..ea1e4d4f --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsVueTsx.vue @@ -0,0 +1,37 @@ + + diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json b/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json new file mode 100644 index 00000000..74acd0f2 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "target": "es2020", + "experimentalDecorators": true + } +} diff --git a/playground/vue-jsx-ts-built-in/decorators/DecoratorsTs.ts b/playground/vue-jsx-ts-built-in/decorators/DecoratorsTs.ts new file mode 100644 index 00000000..229e37da --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators/DecoratorsTs.ts @@ -0,0 +1,31 @@ +import { defineComponent, h, ref } from 'vue' + +function methodDecorator(originalMethod: () => void, context: unknown) { + return function (this: { value: { value: number } }) { + const result = originalMethod.call(this) + this.value.value += 1 + return result + } +} + +export default defineComponent(() => { + class Counter { + value = ref(1) + + @methodDecorator + increment() {} + } + + const counter = new Counter() + const inc = () => counter.increment() + + return () => + h( + 'button', + { + class: 'decorators-ts', + onClick: inc, + }, + `decorators ts ${counter.value.value}`, + ) +}) diff --git a/playground/vue-jsx-ts-built-in/decorators/DecoratorsTsx.tsx b/playground/vue-jsx-ts-built-in/decorators/DecoratorsTsx.tsx new file mode 100644 index 00000000..c7f0b923 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators/DecoratorsTsx.tsx @@ -0,0 +1,27 @@ +import { defineComponent, ref } from 'vue' + +function methodDecorator(originalMethod: () => void, context: unknown) { + return function (this: { value: { value: number } }) { + const result = originalMethod.call(this) + this.value.value += 1 + return result + } +} + +export default defineComponent(() => { + class Counter { + value = ref(2) + + @methodDecorator + increment() {} + } + + const counter = new Counter() + const inc = () => counter.increment() + + return () => ( + + ) +}) diff --git a/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTs.vue b/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTs.vue new file mode 100644 index 00000000..f1864123 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTs.vue @@ -0,0 +1,36 @@ + + diff --git a/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTsx.vue b/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTsx.vue new file mode 100644 index 00000000..f8ec9bf1 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators/DecoratorsVueTsx.vue @@ -0,0 +1,32 @@ + + diff --git a/playground/vue-jsx-ts-built-in/decorators/tsconfig.json b/playground/vue-jsx-ts-built-in/decorators/tsconfig.json new file mode 100644 index 00000000..81894569 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/decorators/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "target": "es2020", + "experimentalDecorators": false + } +} diff --git a/playground/vue-jsx-ts-built-in/index.html b/playground/vue-jsx-ts-built-in/index.html new file mode 100644 index 00000000..a285a008 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/index.html @@ -0,0 +1,2 @@ +
+ diff --git a/playground/vue-jsx-ts-built-in/main.jsx b/playground/vue-jsx-ts-built-in/main.jsx new file mode 100644 index 00000000..e3784603 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/main.jsx @@ -0,0 +1,26 @@ +import { createApp } from 'vue' +import DecoratorsTs from './decorators/DecoratorsTs' +import DecoratorsTsx from './decorators/DecoratorsTsx' +import DecoratorsVueTs from './decorators/DecoratorsVueTs.vue' +import DecoratorsVueTsx from './decorators/DecoratorsVueTsx.vue' +import DecoratorsLegacyTs from './decorators-legacy/DecoratorsTs' +import DecoratorsLegacyTsx from './decorators-legacy/DecoratorsTsx' +import DecoratorsLegacyVueTs from './decorators-legacy/DecoratorsVueTs.vue' +import DecoratorsLegacyVueTsx from './decorators-legacy/DecoratorsVueTsx.vue' + +function App() { + return ( + <> + + + + + + + + + + ) +} + +createApp(App).mount('#app') diff --git a/playground/vue-jsx-ts-built-in/package.json b/playground/vue-jsx-ts-built-in/package.json new file mode 100644 index 00000000..7f534b45 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/package.json @@ -0,0 +1,20 @@ +{ + "name": "@vitejs/test-vue-jsx-decorators", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk vite", + "preview": "vite preview" + }, + "dependencies": { + "vue": "catalog:" + }, + "devDependencies": { + "@babel/plugin-syntax-decorators": "^7.27.1", + "@vitejs/plugin-vue": "workspace:*", + "@vitejs/plugin-vue-jsx": "workspace:*" + } +} diff --git a/playground/vue-jsx-ts-built-in/tsconfig.json b/playground/vue-jsx-ts-built-in/tsconfig.json new file mode 100644 index 00000000..6ea1dd62 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "target": "es2020" + } +} diff --git a/playground/vue-jsx-ts-built-in/vite.config.js b/playground/vue-jsx-ts-built-in/vite.config.js new file mode 100644 index 00000000..7df3b523 --- /dev/null +++ b/playground/vue-jsx-ts-built-in/vite.config.js @@ -0,0 +1,46 @@ +import { defineConfig } from 'vite' +import vueJsxPlugin from '@vitejs/plugin-vue-jsx' +import vuePlugin from '@vitejs/plugin-vue' + +export default defineConfig({ + plugins: [ + vueJsxPlugin({ + include: [/\.tesx$/, /\.[jt]sx$/], + tsTransform: 'built-in', + babelPlugins: [ + // to tests decorators we use only method decorators + // they have the same syntax in 'legacy' and in '2023-11' + ['@babel/plugin-syntax-decorators', { version: '2023-11' }], + ], + }), + vuePlugin(), + { + name: 'jsx-query-plugin', + transform(code, id) { + if (id.includes('?query=true')) { + return ` +import { createVNode as _createVNode } from "vue"; +import { defineComponent, ref } from 'vue'; +export default defineComponent(() => { + const count = ref(6); + + const inc = () => count.value++; + + return () => _createVNode("button", { + "class": "jsx-with-query", + "onClick": inc + }, [count.value]); +}); +` + } + }, + }, + ], + build: { + // to make tests faster + minify: false, + }, + optimizeDeps: { + disabled: true, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aed1e0f4..76b84d23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,6 +147,9 @@ importers: '@babel/core': specifier: ^7.27.7 version: 7.27.7 + '@babel/plugin-syntax-typescript': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.27.7) '@babel/plugin-transform-typescript': specifier: ^7.27.1 version: 7.27.1(@babel/core@7.27.7) @@ -316,6 +319,22 @@ importers: specifier: workspace:* version: link:../../packages/plugin-vue-jsx + playground/vue-jsx-decorators: + dependencies: + vue: + specifier: 'catalog:' + version: 3.5.17(typescript@5.8.3) + devDependencies: + '@babel/plugin-syntax-decorators': + specifier: 7.27.1 + version: 7.27.1(@babel/core@7.27.7) + '@vitejs/plugin-vue': + specifier: workspace:* + version: link:../../packages/plugin-vue + '@vitejs/plugin-vue-jsx': + specifier: workspace:* + version: link:../../packages/plugin-vue-jsx + playground/vue-legacy: dependencies: vue: @@ -548,6 +567,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-assertions@7.26.0': resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} engines: {node: '>=6.9.0'} @@ -5046,6 +5071,11 @@ snapshots: dependencies: '@babel/core': 7.27.7 + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.27.7)': + dependencies: + '@babel/core': 7.27.7 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.27.7)': dependencies: '@babel/core': 7.27.7 @@ -6535,7 +6565,7 @@ snapshots: '@vue/compiler-core@3.5.17': dependencies: - '@babel/parser': 7.27.5 + '@babel/parser': 7.27.7 '@vue/shared': 3.5.17 entities: 4.5.0 estree-walker: 2.0.2 @@ -6565,7 +6595,7 @@ snapshots: '@vue/compiler-sfc@3.5.17': dependencies: - '@babel/parser': 7.27.5 + '@babel/parser': 7.27.7 '@vue/compiler-core': 3.5.17 '@vue/compiler-dom': 3.5.17 '@vue/compiler-ssr': 3.5.17 From 71c5044ac4d331d89288a9363d79bcbe033b0d19 Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 01:37:12 +0300 Subject: [PATCH 2/9] feat(vue-jsx): allow esbuild to perform ts transformation --- .../vue-jsx-ts-built-in/decorators-legacy/tsconfig.json | 2 +- playground/vue-jsx-ts-built-in/decorators/tsconfig.json | 2 +- playground/vue-jsx-ts-built-in/tsconfig.json | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 playground/vue-jsx-ts-built-in/tsconfig.json diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json b/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json index 74acd0f2..02179ebf 100644 --- a/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "target": "es2020", "experimentalDecorators": true diff --git a/playground/vue-jsx-ts-built-in/decorators/tsconfig.json b/playground/vue-jsx-ts-built-in/decorators/tsconfig.json index 81894569..b7e80643 100644 --- a/playground/vue-jsx-ts-built-in/decorators/tsconfig.json +++ b/playground/vue-jsx-ts-built-in/decorators/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "target": "es2020", "experimentalDecorators": false diff --git a/playground/vue-jsx-ts-built-in/tsconfig.json b/playground/vue-jsx-ts-built-in/tsconfig.json deleted file mode 100644 index 6ea1dd62..00000000 --- a/playground/vue-jsx-ts-built-in/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "target": "es2020" - } -} From 3067aa3e512163a587a1e3c2f6c733826bad6dc8 Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 01:38:43 +0300 Subject: [PATCH 3/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/vite.config.js | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/playground/vue-jsx-ts-built-in/vite.config.js b/playground/vue-jsx-ts-built-in/vite.config.js index 7df3b523..7913b285 100644 --- a/playground/vue-jsx-ts-built-in/vite.config.js +++ b/playground/vue-jsx-ts-built-in/vite.config.js @@ -5,7 +5,6 @@ import vuePlugin from '@vitejs/plugin-vue' export default defineConfig({ plugins: [ vueJsxPlugin({ - include: [/\.tesx$/, /\.[jt]sx$/], tsTransform: 'built-in', babelPlugins: [ // to tests decorators we use only method decorators @@ -14,27 +13,6 @@ export default defineConfig({ ], }), vuePlugin(), - { - name: 'jsx-query-plugin', - transform(code, id) { - if (id.includes('?query=true')) { - return ` -import { createVNode as _createVNode } from "vue"; -import { defineComponent, ref } from 'vue'; -export default defineComponent(() => { - const count = ref(6); - - const inc = () => count.value++; - - return () => _createVNode("button", { - "class": "jsx-with-query", - "onClick": inc - }, [count.value]); -}); -` - } - }, - }, ], build: { // to make tests faster From 6ef0a4819de4803fb83675ec240c79c456e2d2aa Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 01:41:17 +0300 Subject: [PATCH 4/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/playground/vue-jsx-ts-built-in/package.json b/playground/vue-jsx-ts-built-in/package.json index 7f534b45..9909db4e 100644 --- a/playground/vue-jsx-ts-built-in/package.json +++ b/playground/vue-jsx-ts-built-in/package.json @@ -1,5 +1,5 @@ { - "name": "@vitejs/test-vue-jsx-decorators", + "name": "@vitejs/test-vue-jsx-ts-built-in", "private": true, "version": "0.0.0", "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76b84d23..b920f367 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -319,14 +319,14 @@ importers: specifier: workspace:* version: link:../../packages/plugin-vue-jsx - playground/vue-jsx-decorators: + playground/vue-jsx-ts-built-in: dependencies: vue: specifier: 'catalog:' version: 3.5.17(typescript@5.8.3) devDependencies: '@babel/plugin-syntax-decorators': - specifier: 7.27.1 + specifier: ^7.27.1 version: 7.27.1(@babel/core@7.27.7) '@vitejs/plugin-vue': specifier: workspace:* From 2dbd9070e635a149c40fdb0c8dd62e04a4438d9a Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 01:58:26 +0300 Subject: [PATCH 5/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/vite.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playground/vue-jsx-ts-built-in/vite.config.js b/playground/vue-jsx-ts-built-in/vite.config.js index 7913b285..03c64ee4 100644 --- a/playground/vue-jsx-ts-built-in/vite.config.js +++ b/playground/vue-jsx-ts-built-in/vite.config.js @@ -1,6 +1,7 @@ import { defineConfig } from 'vite' import vueJsxPlugin from '@vitejs/plugin-vue-jsx' import vuePlugin from '@vitejs/plugin-vue' +import babelPluginSyntaxTypescript from '@babel/plugin-syntax-decorators' export default defineConfig({ plugins: [ @@ -9,7 +10,7 @@ export default defineConfig({ babelPlugins: [ // to tests decorators we use only method decorators // they have the same syntax in 'legacy' and in '2023-11' - ['@babel/plugin-syntax-decorators', { version: '2023-11' }], + [babelPluginSyntaxTypescript, { version: '2023-11' }], ], }), vuePlugin(), From 4c7bbafd55e9d24a67a931036752d1426bf469a3 Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 02:00:59 +0300 Subject: [PATCH 6/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/vite.config.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/playground/vue-jsx-ts-built-in/vite.config.js b/playground/vue-jsx-ts-built-in/vite.config.js index 03c64ee4..48318b0f 100644 --- a/playground/vue-jsx-ts-built-in/vite.config.js +++ b/playground/vue-jsx-ts-built-in/vite.config.js @@ -8,9 +8,12 @@ export default defineConfig({ vueJsxPlugin({ tsTransform: 'built-in', babelPlugins: [ - // to tests decorators we use only method decorators - // they have the same syntax in 'legacy' and in '2023-11' - [babelPluginSyntaxTypescript, { version: '2023-11' }], + [ + babelPluginSyntaxTypescript, + // to test decorators we use only method decorators + // they have the same syntax in 'legacy' and in '2023-11' + { version: '2023-11' }, + ], ], }), vuePlugin(), From 0960987289f9d312bf08d321fdd53bb0db6a0463 Mon Sep 17 00:00:00 2001 From: madeofsun Date: Sat, 5 Jul 2025 02:22:15 +0300 Subject: [PATCH 7/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/vite.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playground/vue-jsx-ts-built-in/vite.config.js b/playground/vue-jsx-ts-built-in/vite.config.js index 48318b0f..cff83d7c 100644 --- a/playground/vue-jsx-ts-built-in/vite.config.js +++ b/playground/vue-jsx-ts-built-in/vite.config.js @@ -1,7 +1,7 @@ import { defineConfig } from 'vite' import vueJsxPlugin from '@vitejs/plugin-vue-jsx' import vuePlugin from '@vitejs/plugin-vue' -import babelPluginSyntaxTypescript from '@babel/plugin-syntax-decorators' +import babelPluginSyntaxDecorators from '@babel/plugin-syntax-decorators' export default defineConfig({ plugins: [ @@ -9,7 +9,7 @@ export default defineConfig({ tsTransform: 'built-in', babelPlugins: [ [ - babelPluginSyntaxTypescript, + babelPluginSyntaxDecorators, // to test decorators we use only method decorators // they have the same syntax in 'legacy' and in '2023-11' { version: '2023-11' }, From 855fe1c9dc85c11b37763a60517aa43a1c01b9e4 Mon Sep 17 00:00:00 2001 From: madeofsun Date: Fri, 11 Jul 2025 21:59:30 +0300 Subject: [PATCH 8/9] feat(vue-jsx): allow esbuild to perform ts transformation --- pnpm-lock.yaml | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 61dc9197..d2fe8568 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,6 +144,9 @@ importers: '@babel/core': specifier: ^7.28.0 version: 7.28.0 + '@babel/plugin-syntax-typescript': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) '@babel/plugin-transform-typescript': specifier: ^7.28.0 version: 7.28.0(@babel/core@7.28.0) @@ -316,6 +319,22 @@ importers: specifier: workspace:* version: link:../../packages/plugin-vue-jsx + playground/vue-jsx-ts-built-in: + dependencies: + vue: + specifier: 'catalog:' + version: 3.5.17(typescript@5.8.3) + devDependencies: + '@babel/plugin-syntax-decorators': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) + '@vitejs/plugin-vue': + specifier: workspace:* + version: link:../../packages/plugin-vue + '@vitejs/plugin-vue-jsx': + specifier: workspace:* + version: link:../../packages/plugin-vue-jsx + playground/vue-legacy: dependencies: vue: @@ -514,11 +533,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.27.5': - resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.27.7': resolution: {integrity: sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==} engines: {node: '>=6.0.0'} @@ -565,6 +579,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-assertions@7.26.0': resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} engines: {node: '>=6.9.0'} @@ -4490,10 +4510,6 @@ snapshots: dependencies: '@babel/types': 7.28.0 - '@babel/parser@7.27.5': - dependencies: - '@babel/types': 7.28.0 - '@babel/parser@7.27.7': dependencies: '@babel/types': 7.28.0 @@ -4541,6 +4557,11 @@ snapshots: dependencies: '@babel/core': 7.28.0 + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -5914,7 +5935,7 @@ snapshots: '@vue/compiler-core@3.5.17': dependencies: - '@babel/parser': 7.27.7 + '@babel/parser': 7.28.0 '@vue/shared': 3.5.17 entities: 4.5.0 estree-walker: 2.0.2 @@ -5944,7 +5965,7 @@ snapshots: '@vue/compiler-sfc@3.5.17': dependencies: - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@vue/compiler-core': 3.5.17 '@vue/compiler-dom': 3.5.17 '@vue/compiler-ssr': 3.5.17 From e4e9dda7870a8aee17714a45d3ee50260d9f4ada Mon Sep 17 00:00:00 2001 From: madeofsun Date: Fri, 11 Jul 2025 22:02:53 +0300 Subject: [PATCH 9/9] feat(vue-jsx): allow esbuild to perform ts transformation --- playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts | 1 + .../vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts index b1d62170..6fbf7b91 100644 --- a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTs.ts @@ -17,6 +17,7 @@ export default defineComponent(() => { class Counter { value = ref(5) + // @ts-expect-error typecheck script does not use local tsconfig.json @methodDecorator increment() {} } diff --git a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx index c1366d94..b2d72435 100644 --- a/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx +++ b/playground/vue-jsx-ts-built-in/decorators-legacy/DecoratorsTsx.tsx @@ -17,6 +17,7 @@ export default defineComponent(() => { class Counter { value = ref(6) + // @ts-expect-error typecheck script does not use local tsconfig.json @methodDecorator increment() {} }