mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2024-11-10 09:39:14 +08:00
fix: throw state.get(...)
when using object slots (#494)
This commit is contained in:
parent
e0d0162d6b
commit
55035e3f1d
@ -13,7 +13,8 @@ export { VueJSXPluginOptions };
|
||||
const hasJSX = (parentPath: NodePath<t.Program>) => {
|
||||
let fileHasJSX = false;
|
||||
parentPath.traverse({
|
||||
JSXElement(path) { // skip ts error
|
||||
JSXElement(path) {
|
||||
// skip ts error
|
||||
fileHasJSX = true;
|
||||
path.stop();
|
||||
},
|
||||
@ -62,14 +63,9 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
if (importMap[name]) {
|
||||
return types.cloneNode(importMap[name]);
|
||||
}
|
||||
const identifier = addNamed(
|
||||
path,
|
||||
name,
|
||||
'vue',
|
||||
{
|
||||
ensureLiveReference: true,
|
||||
},
|
||||
);
|
||||
const identifier = addNamed(path, name, 'vue', {
|
||||
ensureLiveReference: true,
|
||||
});
|
||||
importMap[name] = identifier;
|
||||
return identifier;
|
||||
});
|
||||
@ -80,14 +76,18 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
if (importMap.runtimeIsSlot) {
|
||||
return importMap.runtimeIsSlot;
|
||||
}
|
||||
const { name: isVNodeName } = state.get('isVNode')();
|
||||
const { name: isVNodeName } = state.get(
|
||||
'isVNode',
|
||||
)() as t.Identifier;
|
||||
const isSlot = path.scope.generateUidIdentifier('isSlot');
|
||||
const ast = template.ast`
|
||||
function ${isSlot.name}(s) {
|
||||
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${isVNodeName}(s));
|
||||
}
|
||||
`;
|
||||
const lastImport = (path.get('body') as NodePath[]).filter((p) => p.isImportDeclaration()).pop();
|
||||
const lastImport = (path.get('body') as NodePath[])
|
||||
.filter((p) => p.isImportDeclaration())
|
||||
.pop();
|
||||
if (lastImport) {
|
||||
lastImport.insertAfter(ast);
|
||||
}
|
||||
@ -97,24 +97,57 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
}
|
||||
} else {
|
||||
// var _vue = require('vue');
|
||||
let sourceName = '';
|
||||
let sourceName: t.Identifier;
|
||||
importNames.forEach((name) => {
|
||||
state.set(name, () => {
|
||||
if (!sourceName) {
|
||||
sourceName = addNamespace(
|
||||
path,
|
||||
'vue',
|
||||
{
|
||||
ensureLiveReference: true,
|
||||
},
|
||||
).name;
|
||||
sourceName = addNamespace(path, 'vue', {
|
||||
ensureLiveReference: true,
|
||||
});
|
||||
}
|
||||
return t.memberExpression(t.identifier(sourceName), t.identifier(name));
|
||||
return t.memberExpression(sourceName, t.identifier(name));
|
||||
});
|
||||
});
|
||||
|
||||
const helpers: Record<string, t.Identifier> = {};
|
||||
|
||||
const { enableObjectSlots = true } = state.opts;
|
||||
if (enableObjectSlots) {
|
||||
state.set('@vue/babel-plugin-jsx/runtimeIsSlot', () => {
|
||||
if (helpers.runtimeIsSlot) {
|
||||
return helpers.runtimeIsSlot;
|
||||
}
|
||||
const isSlot = path.scope.generateUidIdentifier('isSlot');
|
||||
const { object: objectName } = state.get(
|
||||
'isVNode',
|
||||
)() as t.MemberExpression;
|
||||
const ast = template.ast`
|
||||
function ${isSlot.name}(s) {
|
||||
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${(objectName as t.Identifier).name}.isVNode(s));
|
||||
}
|
||||
`;
|
||||
|
||||
const nodePaths = path.get('body') as NodePath[];
|
||||
const lastImport = nodePaths
|
||||
.filter(
|
||||
(p) => p.isVariableDeclaration()
|
||||
&& p.node.declarations.some(
|
||||
(d) => (d.id as t.Identifier)?.name === sourceName.name,
|
||||
),
|
||||
)
|
||||
.pop();
|
||||
if (lastImport) {
|
||||
lastImport.insertAfter(ast);
|
||||
}
|
||||
return isSlot;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const { opts: { pragma = '' }, file } = state;
|
||||
const {
|
||||
opts: { pragma = '' },
|
||||
file,
|
||||
} = state;
|
||||
|
||||
if (pragma) {
|
||||
state.set('createVNode', () => t.identifier(pragma));
|
||||
@ -134,13 +167,20 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
const body = path.get('body') as NodePath[];
|
||||
const specifiersMap = new Map<string, t.ImportSpecifier>();
|
||||
|
||||
body.filter((nodePath) => t.isImportDeclaration(nodePath.node)
|
||||
&& nodePath.node.source.value === 'vue')
|
||||
body
|
||||
.filter(
|
||||
(nodePath) => t.isImportDeclaration(nodePath.node)
|
||||
&& nodePath.node.source.value === 'vue',
|
||||
)
|
||||
.forEach((nodePath) => {
|
||||
const { specifiers } = nodePath.node as t.ImportDeclaration;
|
||||
let shouldRemove = false;
|
||||
specifiers.forEach((specifier) => {
|
||||
if (!specifier.loc && t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported)) {
|
||||
if (
|
||||
!specifier.loc
|
||||
&& t.isImportSpecifier(specifier)
|
||||
&& t.isIdentifier(specifier.imported)
|
||||
) {
|
||||
specifiersMap.set(specifier.imported.name, specifier);
|
||||
shouldRemove = true;
|
||||
}
|
||||
@ -154,7 +194,10 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
(imported) => specifiersMap.get(imported)!,
|
||||
);
|
||||
if (specifiers.length) {
|
||||
path.unshiftContainer('body', t.importDeclaration(specifiers, t.stringLiteral('vue')));
|
||||
path.unshiftContainer(
|
||||
'body',
|
||||
t.importDeclaration(specifiers, t.stringLiteral('vue')),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -24,5 +24,3 @@ export interface VueJSXPluginOptions {
|
||||
/** Replace the function used when compiling JSX expressions */
|
||||
pragma?: string;
|
||||
}
|
||||
|
||||
export type ExcludesBoolean = <T>(x: T | false | true) => x is T;
|
||||
|
@ -20,10 +20,12 @@ import {
|
||||
import SlotFlags from './slotFlags';
|
||||
import { PatchFlags } from './patchFlags';
|
||||
import parseDirectives from './parseDirectives';
|
||||
import type { State, ExcludesBoolean, Slots } from './interface';
|
||||
import type { State, Slots } from './interface';
|
||||
|
||||
const xlinkRE = /^xlink([A-Z])/;
|
||||
|
||||
type ExcludesBoolean = <T>(x: T | false | true) => x is T;
|
||||
|
||||
const getJSXAttributeValue = (
|
||||
path: NodePath<t.JSXAttribute>,
|
||||
state: State,
|
||||
|
@ -4,7 +4,8 @@
|
||||
"rootDirs": ["./src"],
|
||||
"outDir": "dist",
|
||||
"downlevelIteration": true,
|
||||
"declaration": true
|
||||
"declaration": true,
|
||||
"jsx": "preserve",
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
@ -11,7 +11,6 @@
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"removeComments": false,
|
||||
"jsx": "preserve",
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom"
|
||||
|
Loading…
Reference in New Issue
Block a user