@@ -13,6 +13,7 @@ use oxc_ast::ast::ImportDeclarationSpecifier;
1313use oxc_parser:: Parser ;
1414use oxc_span:: SourceType ;
1515use std:: collections:: HashMap ;
16+ use std:: fmt:: Write ;
1617
1718/// Transform source code by rewriting aliased imports to the target package
1819///
@@ -84,32 +85,34 @@ fn generate_transformed_import(
8485 match alias {
8586 ImportAlias :: DefaultToNamed ( named_export) => {
8687 // Transform: `import foo from 'pkg'` → `import { named as foo } from 'target'`
87- let mut import_parts = Vec :: new ( ) ;
88+ let mut parts = String :: new ( ) ;
8889
8990 for specifier in specifiers {
9091 match specifier {
9192 ImportDeclarationSpecifier :: ImportDefaultSpecifier ( default_spec) => {
9293 let local_name = default_spec. local . name . as_str ( ) ;
94+ if !parts. is_empty ( ) {
95+ parts. push_str ( ", " ) ;
96+ }
9397 if local_name == named_export {
94- // Same name: `import { styled } from 'pkg'`
95- import_parts. push ( named_export. clone ( ) ) ;
98+ parts. push_str ( named_export) ;
9699 } else {
97- // Different name: `import { styled as foo } from 'pkg'`
98- import_parts. push ( format ! ( "{} as {}" , named_export, local_name) ) ;
100+ write ! ( parts, "{} as {}" , named_export, local_name) . unwrap ( ) ;
99101 }
100102 }
101103 ImportDeclarationSpecifier :: ImportSpecifier ( spec) => {
102- // Keep named imports
103104 let imported = spec. imported . to_string ( ) ;
104105 let local = spec. local . name . as_str ( ) ;
106+ if !parts. is_empty ( ) {
107+ parts. push_str ( ", " ) ;
108+ }
105109 if imported == local {
106- import_parts . push ( imported) ;
110+ parts . push_str ( & imported) ;
107111 } else {
108- import_parts . push ( format ! ( "{} as {}" , imported, local) ) ;
112+ write ! ( parts , "{} as {}" , imported, local) . unwrap ( ) ;
109113 }
110114 }
111115 ImportDeclarationSpecifier :: ImportNamespaceSpecifier ( ns_spec) => {
112- // Namespace imports are kept but shouldn't really happen for CSS-in-JS
113116 return format ! (
114117 "import * as {} from '{}';" ,
115118 ns_spec. local. name. as_str( ) ,
@@ -119,32 +122,31 @@ fn generate_transformed_import(
119122 }
120123 }
121124
122- format ! (
123- "import {{ {} }} from '{}';" ,
124- import_parts. join( ", " ) ,
125- package
126- )
125+ format ! ( "import {{ {} }} from '{}';" , parts, package)
127126 }
128127 ImportAlias :: NamedToNamed => {
129128 // Just change the source, keep specifiers as-is
130129 // `import { style } from 'pkg'` → `import { style } from 'target'`
131- let mut import_parts = Vec :: new ( ) ;
130+ let mut parts = String :: new ( ) ;
132131
133132 for specifier in specifiers {
134133 match specifier {
135134 ImportDeclarationSpecifier :: ImportDefaultSpecifier ( default_spec) => {
136- // Default import in NamedToNamed mode - just keep it
137- // (shouldn't happen for @vanilla-extract/css)
138- import_parts
139- . push ( format ! ( "default as {}" , default_spec. local. name. as_str( ) ) ) ;
135+ if !parts . is_empty ( ) {
136+ parts . push_str ( ", " ) ;
137+ }
138+ write ! ( parts , "default as {}" , default_spec. local. name. as_str( ) ) . unwrap ( ) ;
140139 }
141140 ImportDeclarationSpecifier :: ImportSpecifier ( spec) => {
142141 let imported = spec. imported . to_string ( ) ;
143142 let local = spec. local . name . as_str ( ) ;
143+ if !parts. is_empty ( ) {
144+ parts. push_str ( ", " ) ;
145+ }
144146 if imported == local {
145- import_parts . push ( imported) ;
147+ parts . push_str ( & imported) ;
146148 } else {
147- import_parts . push ( format ! ( "{} as {}" , imported, local) ) ;
149+ write ! ( parts , "{} as {}" , imported, local) . unwrap ( ) ;
148150 }
149151 }
150152 ImportDeclarationSpecifier :: ImportNamespaceSpecifier ( ns_spec) => {
@@ -157,11 +159,7 @@ fn generate_transformed_import(
157159 }
158160 }
159161
160- format ! (
161- "import {{ {} }} from '{}';" ,
162- import_parts. join( ", " ) ,
163- package
164- )
162+ format ! ( "import {{ {} }} from '{}';" , parts, package)
165163 }
166164 }
167165}
0 commit comments