From e16695d87e269000055828f32492690c4cf796b2 Mon Sep 17 00:00:00 2001 From: Amour1688 Date: Wed, 9 Sep 2020 17:07:47 +0800 Subject: [PATCH] feat: optional mergePros --- packages/babel-plugin-jsx/src/buildProps.ts | 30 ++++++++++++++------- packages/babel-plugin-jsx/src/index.ts | 1 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/babel-plugin-jsx/src/buildProps.ts b/packages/babel-plugin-jsx/src/buildProps.ts index 29be732..da4bf27 100644 --- a/packages/babel-plugin-jsx/src/buildProps.ts +++ b/packages/babel-plugin-jsx/src/buildProps.ts @@ -46,7 +46,8 @@ const getJSXAttributeValue = ( const transformJSXSpreadAttribute = ( nodePath: NodePath, path: NodePath, - mergeArgs: (t.ObjectProperty | t.Expression)[], + mergeProps: boolean, + args: (t.ObjectProperty | t.Expression | t.SpreadElement)[], ) => { const argument = path.get('argument') as NodePath; const { properties } = argument.node; @@ -54,9 +55,9 @@ const transformJSXSpreadAttribute = ( if (argument.isIdentifier()) { walksScope(nodePath, (argument.node as t.Identifier).name, SlotFlags.DYNAMIC); } - mergeArgs.push(argument.node); + args.push(mergeProps ? argument.node : t.spreadElement(argument.node)); } 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(); const deduped: t.ObjectProperty[] = []; properties.forEach((prop) => { @@ -146,6 +150,7 @@ const buildProps = (path: NodePath, state: State) => { let hasDynamicKeys = false; const mergeArgs: (t.CallExpression | t.ObjectExpression | t.Identifier)[] = []; + const { mergeProps = true } = state.opts; props .forEach((prop) => { if (prop.isJSXAttribute()) { @@ -273,8 +278,8 @@ const buildProps = (path: NodePath, state: State) => { )); } } else { - if (properties.length) { - mergeArgs.push(t.objectExpression(dedupeProperties(properties))); + if (properties.length && mergeProps) { + mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps))); properties = []; } @@ -283,7 +288,8 @@ const buildProps = (path: NodePath, state: State) => { transformJSXSpreadAttribute( path as NodePath, prop as NodePath, - mergeArgs, + mergeProps, + mergeProps ? mergeArgs : properties, ); } }); @@ -314,10 +320,9 @@ const buildProps = (path: NodePath, state: State) => { } let propsExpression: t.Expression | t.ObjectProperty | t.Literal = t.nullLiteral(); - if (mergeArgs.length) { if (properties.length) { - mergeArgs.push(t.objectExpression(dedupeProperties(properties))); + mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps))); } if (mergeArgs.length > 1) { propsExpression = t.callExpression( @@ -329,7 +334,12 @@ const buildProps = (path: NodePath, state: State) => { propsExpression = mergeArgs[0]; } } 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 { diff --git a/packages/babel-plugin-jsx/src/index.ts b/packages/babel-plugin-jsx/src/index.ts index b45738d..47abea7 100644 --- a/packages/babel-plugin-jsx/src/index.ts +++ b/packages/babel-plugin-jsx/src/index.ts @@ -14,6 +14,7 @@ export type State = { interface Opts { transformOn?: boolean; optimize?: boolean; + mergeProps?: boolean; isCustomElement?: (tag: string) => boolean; }