@@ -8,6 +8,7 @@ import { JsMacroName } from "./constants"
8
8
import {
9
9
type LinguiConfigNormalized ,
10
10
getConfig as loadConfig ,
11
+ LinguiConfig ,
11
12
} from "@lingui/conf"
12
13
13
14
let config : LinguiConfigNormalized
@@ -86,34 +87,50 @@ const getIdentifierPath = ((path: NodePath, node: Identifier) => {
86
87
return foundPath
87
88
} ) as any
88
89
90
+ type MacroImports = {
91
+ corePackage : Set < NodePath < babelTypes . ImportDeclaration > >
92
+ jsxPackage : Set < NodePath < babelTypes . ImportDeclaration > >
93
+ all : Set < NodePath < babelTypes . ImportDeclaration > >
94
+ }
95
+
96
+ const LinguiSymbolToImportMap = {
97
+ Trans : "jsxPackage" ,
98
+ useLingui : "jsxPackage" ,
99
+ i18n : "corePackage" ,
100
+ } satisfies Record < LinguiSymbol , keyof LinguiConfig [ "macro" ] >
101
+
89
102
export default function ( {
90
103
types : t ,
91
104
} : {
92
105
types : typeof babelTypes
93
106
} ) : PluginObj {
94
- function addImport ( state : PluginPass , name : LinguiSymbol ) {
95
- const path = state . get (
96
- "macroImport"
97
- ) as NodePath < babelTypes . ImportDeclaration >
107
+ function addImport (
108
+ macroImports : MacroImports ,
109
+ state : PluginPass ,
110
+ name : LinguiSymbol
111
+ ) {
112
+ const [ path ] = macroImports [ LinguiSymbolToImportMap [ name ] ]
98
113
99
114
const config = state . get ( "linguiConfig" ) as LinguiConfigNormalized
100
115
101
116
if ( ! state . get ( "has_import_" + name ) ) {
102
117
state . set ( "has_import_" + name , true )
103
118
const [ moduleSource , importName ] = config . runtimeConfigModule [ name ]
104
119
105
- const [ newPath ] = path . insertAfter (
106
- t . importDeclaration (
107
- [
108
- t . importSpecifier (
109
- getSymbolIdentifier ( state , name ) ,
110
- t . identifier ( importName )
111
- ) ,
112
- ] ,
113
- t . stringLiteral ( moduleSource )
114
- )
120
+ const importDecl = t . importDeclaration (
121
+ [
122
+ t . importSpecifier (
123
+ getSymbolIdentifier ( state , name ) ,
124
+ t . identifier ( importName )
125
+ ) ,
126
+ ] ,
127
+ t . stringLiteral ( moduleSource )
115
128
)
116
129
130
+ importDecl . loc = path . node . loc
131
+
132
+ const [ newPath ] = path . insertAfter ( importDecl )
133
+
117
134
path . parentPath . scope . registerDeclaration ( newPath )
118
135
}
119
136
@@ -122,18 +139,34 @@ export default function ({
122
139
)
123
140
}
124
141
125
- function getMacroImports ( path : NodePath < Program > ) {
126
- const linguiPackages = new Set ( [
127
- ...config . macro . corePackage ,
128
- ...config . macro . jsxPackage ,
129
- ] )
142
+ function getMacroImports ( path : NodePath < Program > ) : MacroImports {
143
+ const corePackage = new Set (
144
+ path
145
+ . get ( "body" )
146
+ . filter (
147
+ ( statement ) =>
148
+ statement . isImportDeclaration ( ) &&
149
+ config . macro . corePackage . includes (
150
+ statement . get ( "source" ) . node . value
151
+ )
152
+ ) as NodePath < babelTypes . ImportDeclaration > [ ]
153
+ )
130
154
131
- return path . get ( "body" ) . filter ( ( statement ) => {
132
- return (
133
- statement . isImportDeclaration ( ) &&
134
- linguiPackages . has ( statement . get ( "source" ) . node . value )
135
- )
136
- } )
155
+ const jsxPackage = new Set (
156
+ path
157
+ . get ( "body" )
158
+ . filter (
159
+ ( statement ) =>
160
+ statement . isImportDeclaration ( ) &&
161
+ config . macro . jsxPackage . includes ( statement . get ( "source" ) . node . value )
162
+ ) as NodePath < babelTypes . ImportDeclaration > [ ]
163
+ )
164
+
165
+ return {
166
+ corePackage,
167
+ jsxPackage,
168
+ all : new Set ( [ ...corePackage , ...jsxPackage ] ) ,
169
+ }
137
170
}
138
171
139
172
function getSymbolIdentifier (
@@ -184,17 +217,15 @@ export default function ({
184
217
185
218
const macroImports = getMacroImports ( path )
186
219
187
- if ( ! macroImports . length ) {
220
+ if ( ! macroImports . all . size ) {
188
221
return
189
222
}
190
223
191
- state . set ( "macroImport" , macroImports [ 0 ] )
192
-
193
224
state . set ( "linguiIdentifiers" , {
194
225
i18n : path . scope . generateUidIdentifier ( "i18n" ) ,
195
226
Trans : path . scope . generateUidIdentifier ( "Trans" ) ,
196
227
useLingui : path . scope . generateUidIdentifier ( "useLingui" ) ,
197
- } )
228
+ } satisfies Record < LinguiSymbol , babelTypes . Identifier > )
198
229
199
230
path . traverse (
200
231
{
@@ -224,7 +255,7 @@ export default function ({
224
255
225
256
if ( newNode ) {
226
257
const [ newPath ] = path . replaceWith ( newNode )
227
- addImport ( state , "Trans" ) . reference ( newPath )
258
+ addImport ( macroImports , state , "Trans" ) . reference ( newPath )
228
259
}
229
260
} ,
230
261
@@ -261,11 +292,13 @@ export default function ({
261
292
const [ newPath ] = path . replaceWith ( newNode )
262
293
263
294
if ( macro . needsUseLinguiImport ) {
264
- addImport ( state , "useLingui" ) . reference ( newPath )
295
+ addImport ( macroImports , state , "useLingui" ) . reference (
296
+ newPath
297
+ )
265
298
}
266
299
267
300
if ( macro . needsI18nImport ) {
268
- addImport ( state , "i18n" ) . reference ( newPath )
301
+ addImport ( macroImports , state , "i18n" ) . reference ( newPath )
269
302
}
270
303
}
271
304
} ,
@@ -275,7 +308,7 @@ export default function ({
275
308
} ,
276
309
exit ( path , state ) {
277
310
const macroImports = getMacroImports ( path )
278
- macroImports . forEach ( ( path ) => path . remove ( ) )
311
+ macroImports . all . forEach ( ( path ) => path . remove ( ) )
279
312
} ,
280
313
} ,
281
314
} as Visitor < PluginPass > ,
0 commit comments