diff --git a/packages/plugin-vue-jsx/src/index.ts b/packages/plugin-vue-jsx/src/index.ts index f79ea502..9fe6596d 100644 --- a/packages/plugin-vue-jsx/src/index.ts +++ b/packages/plugin-vue-jsx/src/index.ts @@ -1,6 +1,6 @@ import { createHash } from 'node:crypto' import path from 'node:path' -import type { types } from '@babel/core' +import { types } from '@babel/core' import * as babel from '@babel/core' import jsx from '@vue/babel-plugin-jsx' import { createFilter, normalizePath } from 'vite' @@ -112,6 +112,36 @@ function vueJsxPlugin(options: Options = {}): Plugin { }, } }) + } else { + plugins.push(() => { + return { + visitor: { + ExportDefaultDeclaration: { + enter(_path: babel.NodePath) { + if (isDefineComponentCall(_path.node.declaration)) { + const declaration = _path.node + .declaration as CallExpression + const nodesPath = _path.replaceWithMultiple([ + types.variableDeclaration('const', [ + types.variableDeclarator( + types.identifier('__default__'), + types.callExpression( + declaration.callee, + declaration.arguments, + ), + ), + ]), + types.exportDefaultDeclaration( + types.identifier('__default__'), + ), + ]) + _path.scope.registerDeclaration(nodesPath[0]) + } + }, + }, + }, + } + }) } const result = babel.transformSync(code, { @@ -140,7 +170,6 @@ function vueJsxPlugin(options: Options = {}): Plugin { // check for hmr injection const declaredComponents: string[] = [] const hotComponents: HotComponent[] = [] - let hasDefault = false for (const node of result.ast!.program.body) { if (node.type === 'VariableDeclaration') { @@ -195,7 +224,6 @@ function vueJsxPlugin(options: Options = {}): Plugin { }) } } else if (isDefineComponentCall(node.declaration)) { - hasDefault = true hotComponents.push({ local: '__default__', exported: 'default', @@ -206,14 +234,6 @@ function vueJsxPlugin(options: Options = {}): Plugin { } if (hotComponents.length) { - if (hasDefault && (needHmr || ssr)) { - result.code = - result.code!.replace( - /export default defineComponent/g, - `const __default__ = defineComponent`, - ) + `\nexport default __default__` - } - if (needHmr && !ssr && !/\?vue&type=script/.test(id)) { let code = result.code let callbackCode = `` diff --git a/playground/vue-jsx/ExportDefault.jsx b/playground/vue-jsx/ExportDefault.jsx new file mode 100644 index 00000000..9bbd0ec7 --- /dev/null +++ b/playground/vue-jsx/ExportDefault.jsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +export default defineComponent({ + render() { + return export default defineComponent + }, +}) diff --git a/playground/vue-jsx/__tests__/vue-jsx.spec.ts b/playground/vue-jsx/__tests__/vue-jsx.spec.ts index 7a951f23..d028550b 100644 --- a/playground/vue-jsx/__tests__/vue-jsx.spec.ts +++ b/playground/vue-jsx/__tests__/vue-jsx.spec.ts @@ -11,6 +11,9 @@ test('should render', async () => { expect(await page.textContent('.jsx-with-query')).toMatch('6') expect(await page.textContent('.other-ext')).toMatch('Other Ext') expect(await page.textContent('.ts-import')).toMatch('success') + expect(await page.textContent('.export-default')).toMatch( + 'export default defineComponent', + ) }) test('should update', async () => { diff --git a/playground/vue-jsx/main.jsx b/playground/vue-jsx/main.jsx index f13e60c4..e8414322 100644 --- a/playground/vue-jsx/main.jsx +++ b/playground/vue-jsx/main.jsx @@ -8,6 +8,7 @@ import JsxSetupSyntax from './setup-syntax-jsx.vue' // eslint-disable-next-line import JsxWithQuery from './Query.jsx?query=true' import TsImport from './TsImport.vue' +import ExportDefault from './ExportDefault' function App() { return ( @@ -22,6 +23,7 @@ function App() { + ) }