mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2025-07-08 04:29:07 +08:00
fix(babel-plugin-jsx):
prevent transform aliased Fragment and KeepAlive's children to slots
This commit is contained in:
@ -119,6 +119,31 @@ export default declare<VueJSXPluginOptions, BabelCore.PluginObj<State>>(
|
|||||||
return isSlot;
|
return isSlot;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vueImportMap: Record<
|
||||||
|
string,
|
||||||
|
(t.MemberExpression | t.Identifier)[]
|
||||||
|
> = {};
|
||||||
|
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 {
|
} else {
|
||||||
// var _vue = require('vue');
|
// var _vue = require('vue');
|
||||||
let sourceName: t.Identifier;
|
let sourceName: t.Identifier;
|
||||||
|
@ -30,11 +30,23 @@ export const isDirective = (src: string): boolean =>
|
|||||||
/**
|
/**
|
||||||
* Should transformed to slots
|
* Should transformed to slots
|
||||||
* @param tag string
|
* @param tag string
|
||||||
|
* @param state State
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
// if _Fragment is already imported, it will end with number
|
// if _Fragment is already imported, it will end with number
|
||||||
export const shouldTransformedToSlots = (tag: string) =>
|
export const shouldTransformedToSlots = (tag: string, state?: State) => {
|
||||||
!(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE);
|
if (state) {
|
||||||
|
const vueImportMap = state.get('vueImportMap');
|
||||||
|
for (const name of [FRAGMENT, KEEP_ALIVE]) {
|
||||||
|
if (vueImportMap[name]) {
|
||||||
|
if(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
|
* Check if a Node is a component
|
||||||
@ -57,7 +69,7 @@ export const checkIsComponent = (
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
!state.opts.isCustomElement?.(tag) &&
|
!state.opts.isCustomElement?.(tag) &&
|
||||||
shouldTransformedToSlots(tag) &&
|
shouldTransformedToSlots(tag, state) &&
|
||||||
!isHTMLTag(tag) &&
|
!isHTMLTag(tag) &&
|
||||||
!isSVGTag(tag)
|
!isSVGTag(tag)
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`_Fragment already imported > _Fragment already imported 1`] = `
|
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 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`] = `
|
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`] = `
|
exports[`named import specifier \`Keep Alive\` > named import specifier \`Keep Alive\` 1`] = `
|
||||||
"import { KeepAlive, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue';
|
"import { KeepAlive, KeepAlive as KeepAliveA, createTextVNode as _createTextVNode, createVNode as _createVNode } from 'vue';
|
||||||
_createVNode(KeepAlive, null, [_createTextVNode("123")]);"
|
const Root1 = _createVNode(KeepAlive, null, [_createTextVNode("root1")]);
|
||||||
|
const Root2 = _createVNode(KeepAliveA, null, [_createTextVNode("root2")]);"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`namespace specifier \`Keep Alive\` > namespace specifier \`Keep Alive\` 1`] = `
|
exports[`namespace specifier \`Keep Alive\` > namespace specifier \`Keep Alive\` 1`] = `
|
||||||
|
@ -173,9 +173,10 @@ const transpile = (source: string, options: VueJSXPluginOptions = {}) =>
|
|||||||
{
|
{
|
||||||
name: 'named import specifier `Keep Alive`',
|
name: 'named import specifier `Keep Alive`',
|
||||||
from: `
|
from: `
|
||||||
import { KeepAlive } from 'vue';
|
import { KeepAlive, KeepAlive as KeepAliveA } from 'vue';
|
||||||
|
|
||||||
<KeepAlive>123</KeepAlive>
|
const Root1 = <KeepAlive>root1</KeepAlive>
|
||||||
|
const Root2 = <KeepAliveA>root2</KeepAliveA>
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -353,9 +354,10 @@ const fragmentTests = [
|
|||||||
{
|
{
|
||||||
name: '_Fragment already imported',
|
name: '_Fragment already imported',
|
||||||
from: `
|
from: `
|
||||||
import { Fragment as _Fragment } from 'vue'
|
import { Fragment as _Fragment, Fragment as _FragmentA } from 'vue'
|
||||||
const Root1 = () => <>root1</>
|
const Root1 = () => <>root1</>
|
||||||
const Root2 = () => <_Fragment>root2</_Fragment>
|
const Root2 = () => <_Fragment>root2</_Fragment>
|
||||||
|
const Root3 = () => <_FragmentA>root3</_FragmentA>
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
Reference in New Issue
Block a user