@@ -22,6 +22,72 @@ export const decorateComponentExportsWithProps = (
22
22
return uid ;
23
23
}
24
24
25
+ /**
26
+ * Rewrite any re-exports for named components (`default Component`, `HydrateFallback`, `ErrorBoundary`)
27
+ * into `export const <name> = <expr>` form in preparation for adding props HOCs in the next traversal.
28
+ *
29
+ * Case 1: `export { name, ... }` or `export { value as name, ... }`
30
+ * -> Rename `name` to `uid` where `uid` is a new unique identifier
31
+ * -> Insert `export const name = uid`
32
+ *
33
+ * Case 2: `export { name1, value as name 2, ... } from "source"`
34
+ * -> Insert `import { name as uid }` where `uid` is a new unique identifier
35
+ * -> Insert `export const name = uid`
36
+ */
37
+ traverse ( ast , {
38
+ ExportNamedDeclaration ( path ) {
39
+ if ( path . node . declaration ) return ;
40
+ const { source } = path . node ;
41
+
42
+ const exports : Array < {
43
+ uid : Babel . Identifier ;
44
+ local : Babel . Identifier ;
45
+ exported : Babel . Identifier ;
46
+ } > = [ ] ;
47
+ for ( const specifier of path . get ( "specifiers" ) ) {
48
+ if ( specifier . isExportSpecifier ( ) ) {
49
+ const { local, exported } = specifier . node ;
50
+ const { name } = local ;
51
+ if ( ! t . isIdentifier ( exported ) ) continue ;
52
+ const uid = path . scope . generateUidIdentifier ( `_${ name } ` ) ;
53
+ if ( exported . name === "default" || isNamedComponentExport ( name ) ) {
54
+ exports . push ( { uid, local, exported } ) ;
55
+ specifier . remove ( ) ;
56
+ }
57
+ }
58
+ }
59
+ if ( exports . length === 0 ) return ;
60
+
61
+ if ( source != null ) {
62
+ // `import { local as uid } from "source"`
63
+ path . insertAfter ( [
64
+ t . importDeclaration (
65
+ exports . map ( ( { local, uid } ) => t . importSpecifier ( uid , local ) ) ,
66
+ source ,
67
+ ) ,
68
+ ] ) ;
69
+ } else {
70
+ for ( const { local, uid } of exports ) {
71
+ path . scope . getBinding ( local . name ) ?. scope . rename ( uid . name ) ;
72
+ }
73
+ }
74
+
75
+ // `export const exported = uid`
76
+ path . insertAfter (
77
+ exports . map ( ( { uid, exported } ) => {
78
+ if ( exported . name === "default" ) {
79
+ return t . exportDefaultDeclaration ( uid ) ;
80
+ }
81
+ return t . exportNamedDeclaration (
82
+ t . variableDeclaration ( "const" , [
83
+ t . variableDeclarator ( exported , uid ) ,
84
+ ] ) ,
85
+ ) ;
86
+ } ) ,
87
+ ) ;
88
+ } ,
89
+ } ) ;
90
+
25
91
traverse ( ast , {
26
92
ExportDeclaration ( path ) {
27
93
if ( path . isExportDefaultDeclaration ( ) ) {
0 commit comments