feat: optional mergePros

This commit is contained in:
Amour1688 2020-09-09 17:07:47 +08:00
parent 45290ca1ee
commit e16695d87e
2 changed files with 21 additions and 10 deletions

View File

@ -46,7 +46,8 @@ const getJSXAttributeValue = (
const transformJSXSpreadAttribute = ( const transformJSXSpreadAttribute = (
nodePath: NodePath, nodePath: NodePath,
path: NodePath<t.JSXSpreadAttribute>, path: NodePath<t.JSXSpreadAttribute>,
mergeArgs: (t.ObjectProperty | t.Expression)[], mergeProps: boolean,
args: (t.ObjectProperty | t.Expression | t.SpreadElement)[],
) => { ) => {
const argument = path.get('argument') as NodePath<t.ObjectExpression>; const argument = path.get('argument') as NodePath<t.ObjectExpression>;
const { properties } = argument.node; const { properties } = argument.node;
@ -54,9 +55,9 @@ const transformJSXSpreadAttribute = (
if (argument.isIdentifier()) { if (argument.isIdentifier()) {
walksScope(nodePath, (argument.node as t.Identifier).name, SlotFlags.DYNAMIC); walksScope(nodePath, (argument.node as t.Identifier).name, SlotFlags.DYNAMIC);
} }
mergeArgs.push(argument.node); args.push(mergeProps ? argument.node : t.spreadElement(argument.node));
} else { } else {
mergeArgs.push(t.objectExpression(properties)); args.push(t.objectExpression(properties));
} }
}; };
@ -71,7 +72,10 @@ const mergeAsArray = (existing: t.ObjectProperty, incoming: t.ObjectProperty) =>
} }
}; };
const dedupeProperties = (properties: t.ObjectProperty[] = []) => { const dedupeProperties = (properties: t.ObjectProperty[] = [], mergeProps?: boolean) => {
if (!mergeProps) {
return properties;
}
const knownProps = new Map<string, t.ObjectProperty>(); const knownProps = new Map<string, t.ObjectProperty>();
const deduped: t.ObjectProperty[] = []; const deduped: t.ObjectProperty[] = [];
properties.forEach((prop) => { properties.forEach((prop) => {
@ -146,6 +150,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
let hasDynamicKeys = false; let hasDynamicKeys = false;
const mergeArgs: (t.CallExpression | t.ObjectExpression | t.Identifier)[] = []; const mergeArgs: (t.CallExpression | t.ObjectExpression | t.Identifier)[] = [];
const { mergeProps = true } = state.opts;
props props
.forEach((prop) => { .forEach((prop) => {
if (prop.isJSXAttribute()) { if (prop.isJSXAttribute()) {
@ -273,8 +278,8 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
)); ));
} }
} else { } else {
if (properties.length) { if (properties.length && mergeProps) {
mergeArgs.push(t.objectExpression(dedupeProperties(properties))); mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
properties = []; properties = [];
} }
@ -283,7 +288,8 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
transformJSXSpreadAttribute( transformJSXSpreadAttribute(
path as NodePath, path as NodePath,
prop as NodePath<t.JSXSpreadAttribute>, prop as NodePath<t.JSXSpreadAttribute>,
mergeArgs, mergeProps,
mergeProps ? mergeArgs : properties,
); );
} }
}); });
@ -314,10 +320,9 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
} }
let propsExpression: t.Expression | t.ObjectProperty | t.Literal = t.nullLiteral(); let propsExpression: t.Expression | t.ObjectProperty | t.Literal = t.nullLiteral();
if (mergeArgs.length) { if (mergeArgs.length) {
if (properties.length) { if (properties.length) {
mergeArgs.push(t.objectExpression(dedupeProperties(properties))); mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
} }
if (mergeArgs.length > 1) { if (mergeArgs.length > 1) {
propsExpression = t.callExpression( propsExpression = t.callExpression(
@ -329,7 +334,12 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
propsExpression = mergeArgs[0]; propsExpression = mergeArgs[0];
} }
} else if (properties.length) { } else if (properties.length) {
propsExpression = t.objectExpression(dedupeProperties(properties)); // single no need for spread
if (properties.length === 1 && t.isSpreadElement(properties[0])) {
propsExpression = (properties[0] as unknown as t.SpreadElement).argument;
} else {
propsExpression = t.objectExpression(dedupeProperties(properties, mergeProps));
}
} }
return { return {

View File

@ -14,6 +14,7 @@ export type State = {
interface Opts { interface Opts {
transformOn?: boolean; transformOn?: boolean;
optimize?: boolean; optimize?: boolean;
mergeProps?: boolean;
isCustomElement?: (tag: string) => boolean; isCustomElement?: (tag: string) => boolean;
} }