@@ -87,23 +87,33 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
8787 } ) ) ;
8888 buffer = '' ;
8989 }
90+
91+ const FRAGMENT_EXPR = dottedIdentifier ( 'React.Fragment' ) ;
92+
93+ function isFragmentName ( node ) {
94+ return t . isNodesEquivalent ( FRAGMENT_EXPR , node ) ;
95+ }
9096
91- function getName ( node ) {
92- switch ( node . type ) {
93- case 'JSXMemberExpression' :
94- return ` ${ node . object . name } . ${ node . property . name } `
95-
96- default :
97- return node . name ;
97+ function isComponentName ( node ) {
98+ return ! t . isIdentifier ( node ) || node . name . match ( / ^ [ $ _ A - Z ] / ) ;
99+ }
100+
101+ function getNameExpr ( node ) {
102+ if ( ! t . isJSXMemberExpression ( node ) ) {
103+ return t . identifier ( node . name ) ;
98104 }
105+ return t . memberExpression (
106+ getNameExpr ( node . object ) ,
107+ t . identifier ( node . property . name )
108+ ) ;
99109 }
100110
101111 function processChildren ( node , name , isFragment ) {
102112 const children = t . react . buildChildren ( node ) ;
103113 if ( children && children . length !== 0 ) {
104114 if ( ! isFragment ) {
105115 raw ( '>' ) ;
106- }
116+ }
107117 for ( let i = 0 ; i < children . length ; i ++ ) {
108118 let child = children [ i ] ;
109119 if ( t . isStringLiteral ( child ) ) {
@@ -119,17 +129,17 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
119129 }
120130
121131 if ( ! isFragment ) {
122- if ( name . match ( / ( ^ [ $ _ A - Z ] | \. ) / ) ) {
132+ if ( isComponentName ( name ) ) {
123133 raw ( '</' ) ;
124- expr ( t . identifier ( name ) ) ;
134+ expr ( name ) ;
125135 raw ( '>' ) ;
126136 }
127137 else {
128138 raw ( '</' ) ;
129- raw ( name ) ;
139+ raw ( name . name ) ;
130140 raw ( '>' ) ;
131141 }
132- }
142+ }
133143 }
134144 else if ( ! isFragment ) {
135145 raw ( '/>' ) ;
@@ -138,17 +148,17 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
138148
139149 function processNode ( node , path , isRoot ) {
140150 const open = node . openingElement ;
141- const name = getName ( open . name ) ;
142- const isFragment = name === 'React.Fragment' ;
143-
151+ const name = getNameExpr ( open . name ) ;
152+ const isFragment = isFragmentName ( name ) ;
153+
144154 if ( ! isFragment ) {
145- if ( name . match ( / ( ^ [ $ _ A - Z ] | \. ) / ) ) {
155+ if ( isComponentName ( name ) ) {
146156 raw ( '<' ) ;
147- expr ( t . identifier ( name ) ) ;
157+ expr ( name ) ;
148158 }
149159 else {
150160 raw ( '<' ) ;
151- raw ( name ) ;
161+ raw ( name . name ) ;
152162 }
153163
154164 if ( open . attributes ) {
@@ -198,12 +208,13 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
198208 expressions . length = 0 ;
199209
200210 if ( isFragment ) {
201- processChildren ( path . node , '' , true ) ;
211+ processChildren ( path . node , null , true ) ;
202212 commit ( ) ;
203213 const template = t . templateLiteral ( quasis , expressions ) ;
204214 const replacement = t . taggedTemplateExpression ( tag , template ) ;
205215 path . replaceWith ( replacement ) ;
206- } else {
216+ }
217+ else {
207218 processNode ( path . node , path , true ) ;
208219 }
209220
0 commit comments