diff --git a/packages/babel-plugin-jsx/src/index.ts b/packages/babel-plugin-jsx/src/index.ts index 50654a47..8daaf6d2 100644 --- a/packages/babel-plugin-jsx/src/index.ts +++ b/packages/babel-plugin-jsx/src/index.ts @@ -119,6 +119,28 @@ export default declare>( return isSlot; }); } + + const vueImportMap: Record = {}; + state.set('vueImportMap', vueImportMap); + path.node.body.forEach((statement) => { + if (t.isImportDeclaration(statement)) { + const { source, specifiers } = statement; + if (source.value === 'vue') { + specifiers.forEach((specifier) => { + if ( + t.isImportSpecifier(specifier) && + t.isIdentifier(specifier.imported) + ) { + const name = specifier.imported.name; + if (!vueImportMap[name]) { + vueImportMap[name] = []; + } + vueImportMap[name].push(specifier.local); + } + }); + } + } + }); } else { // var _vue = require('vue'); let sourceName: t.Identifier; diff --git a/packages/babel-plugin-jsx/src/utils.ts b/packages/babel-plugin-jsx/src/utils.ts index bc64ab58..2117b218 100644 --- a/packages/babel-plugin-jsx/src/utils.ts +++ b/packages/babel-plugin-jsx/src/utils.ts @@ -30,11 +30,24 @@ export const isDirective = (src: string): boolean => /** * Should transformed to slots * @param tag string + * @param state State * @returns boolean */ // if _Fragment is already imported, it will end with number -export const shouldTransformedToSlots = (tag: string) => - !(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE); +export const shouldTransformedToSlots = (tag: string, state?: State) => { + if (state) { + const vueImportMap = state.get('vueImportMap'); + for (const name of [FRAGMENT, KEEP_ALIVE]) { + if ( + vueImportMap[name] && + vueImportMap[name].some((id: t.Identifier) => id.name === tag) + ) { + return false; + } + } + } + return !(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE); +}; /** * Check if a Node is a component @@ -57,7 +70,7 @@ export const checkIsComponent = ( return ( !state.opts.isCustomElement?.(tag) && - shouldTransformedToSlots(tag) && + shouldTransformedToSlots(tag, state) && !isHTMLTag(tag) && !isSVGTag(tag) ); diff --git a/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap b/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap index c4c2f986..1c95f332 100644 --- a/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap +++ b/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap @@ -1,9 +1,10 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`_Fragment already imported > _Fragment already imported 1`] = ` -"import { Fragment as _Fragment, Fragment as _Fragment2, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue'; +"import { Fragment as _Fragment, Fragment as _FragmentA, Fragment as _Fragment2, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue'; const Root1 = () => _createVNode(_Fragment2, null, [_createTextVNode("root1")]); -const Root2 = () => _createVNode(_Fragment, null, [_createTextVNode("root2")]);" +const Root2 = () => _createVNode(_Fragment, null, [_createTextVNode("root2")]); +const Root3 = () => _createVNode(_FragmentA, null, [_createTextVNode("root3")]);" `; exports[`MereProps Order > MereProps Order 1`] = ` @@ -130,8 +131,9 @@ _createVNode("foo", null, [_createVNode("span", null, [_createTextVNode("foo")]) `; exports[`named import specifier \`Keep Alive\` > named import specifier \`Keep Alive\` 1`] = ` -"import { KeepAlive, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue'; -_createVNode(KeepAlive, null, [_createTextVNode("123")]);" +"import { KeepAlive, KeepAlive as KeepAliveA, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue'; +const Root1 = _createVNode(KeepAlive, null, [_createTextVNode("root1")]); +const Root2 = _createVNode(KeepAliveA, null, [_createTextVNode("root2")]);" `; exports[`namespace specifier \`Keep Alive\` > namespace specifier \`Keep Alive\` 1`] = ` diff --git a/packages/babel-plugin-jsx/test/snapshot.test.ts b/packages/babel-plugin-jsx/test/snapshot.test.ts index 00e92c9c..8e8af674 100644 --- a/packages/babel-plugin-jsx/test/snapshot.test.ts +++ b/packages/babel-plugin-jsx/test/snapshot.test.ts @@ -173,9 +173,10 @@ const transpile = (source: string, options: VueJSXPluginOptions = {}) => { name: 'named import specifier `Keep Alive`', from: ` - import { KeepAlive } from 'vue'; + import { KeepAlive, KeepAlive as KeepAliveA } from 'vue'; - 123 + const Root1 = root1 + const Root2 = root2 `, }, { @@ -353,9 +354,10 @@ const fragmentTests = [ { name: '_Fragment already imported', from: ` - import { Fragment as _Fragment } from 'vue' + import { Fragment as _Fragment, Fragment as _FragmentA } from 'vue' const Root1 = () => <>root1 const Root2 = () => <_Fragment>root2 + const Root3 = () => <_FragmentA>root3 `, }, ];