@@ -78,7 +78,6 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
7878
7979 const hoistIndex = code . match ( hashbangRE ) ?. [ 0 ] . length ?? 0
8080
81- let hoistedCode = ''
8281 let hoistedVitestImports = ''
8382
8483 let uid = 0
@@ -148,6 +147,7 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
148147 }
149148
150149 const declaredConst = new Set < string > ( )
150+ const hoistedNodes : Node [ ] = [ ]
151151
152152 esmWalker ( ast , {
153153 onIdentifier ( id , info , parentStack ) {
@@ -184,12 +184,8 @@ export function hoistMocks(code: string, id: string, parse: PluginContext['parse
184184 ) {
185185 const methodName = node . callee . property . name
186186
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 )
193189
194190 if ( methodName === 'hoisted' ) {
195191 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
212208
213209 if ( canMoveDeclaration ) {
214210 // 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 )
219212 }
220213 else {
221214 // 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 )
226216 }
227217 }
228218 }
229219 } ,
230220 } )
231221
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+
232237 if ( hoistedCode || hoistedVitestImports ) {
233238 s . prepend (
234239 hoistedVitestImports
0 commit comments