@@ -78,7 +78,6 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
78
78
79
79
const hoistIndex = code . match ( hashbangRE ) ?. [ 0 ] . length ?? 0
80
80
81
- let hoistedCode = ''
82
81
let hoistedVitestImports = ''
83
82
84
83
let uid = 0
@@ -148,6 +147,7 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
148
147
}
149
148
150
149
const declaredConst = new Set < string > ( )
150
+ const hoistedNodes : Node [ ] = [ ]
151
151
152
152
esmWalker ( ast , {
153
153
onIdentifier ( id , info , parentStack ) {
@@ -184,12 +184,8 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
184
184
) {
185
185
const methodName = node . callee . property . name
186
186
187
- if ( methodName === 'mock' || methodName === 'unmock' ) {
188
- const end = getBetterEnd ( code , node )
189
- const nodeCode = code . slice ( node . start , end )
190
- hoistedCode += `${ nodeCode } ${ nodeCode . endsWith ( '\n' ) ? '' : '\n' } `
191
- s . remove ( node . start , end )
192
- }
187
+ if ( methodName === 'mock' || methodName === 'unmock' )
188
+ hoistedNodes . push ( node )
193
189
194
190
if ( methodName === 'hoisted' ) {
195
191
const declarationNode = findNodeAround ( ast , node . start , 'VariableDeclaration' ) ?. node as Positioned < VariableDeclaration > | undefined
@@ -212,23 +208,32 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
212
208
213
209
if ( canMoveDeclaration ) {
214
210
// hoist "const variable = vi.hoisted(() => {})"
215
- const end = getBetterEnd ( code , declarationNode )
216
- const nodeCode = code . slice ( declarationNode . start , end )
217
- hoistedCode += `${ nodeCode } ${ nodeCode . endsWith ( '\n' ) ? '' : '\n' } `
218
- s . remove ( declarationNode . start , end )
211
+ hoistedNodes . push ( declarationNode )
219
212
}
220
213
else {
221
214
// hoist "vi.hoisted(() => {})"
222
- const end = getBetterEnd ( code , node )
223
- const nodeCode = code . slice ( node . start , end )
224
- hoistedCode += `${ nodeCode } ${ nodeCode . endsWith ( '\n' ) ? '' : '\n' } `
225
- s . remove ( node . start , end )
215
+ hoistedNodes . push ( node )
226
216
}
227
217
}
228
218
}
229
219
} ,
230
220
} )
231
221
222
+ // Wait for imports to be hoisted and then hoist the mocks
223
+ const hoistedCode = hoistedNodes . map ( ( node ) => {
224
+ const end = getBetterEnd ( code , node )
225
+ /**
226
+ * In the following case, we need to change the `user` to user: __vi_import_x__.user
227
+ * So we should get the latest code from `s`.
228
+ *
229
+ * import user from './user'
230
+ * vi.mock('./mock.js', () => ({ getSession: vi.fn().mockImplementation(() => ({ user })) }))
231
+ */
232
+ const nodeCode = s . slice ( node . start , end )
233
+ s . remove ( node . start , end )
234
+ return `${ nodeCode } ${ nodeCode . endsWith ( '\n' ) ? '' : '\n' } `
235
+ } ) . join ( '' )
236
+
232
237
if ( hoistedCode || hoistedVitestImports ) {
233
238
s . prepend (
234
239
hoistedVitestImports
0 commit comments