Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dynamicImportSettled also waits for nested imports #2389

Merged
merged 4 commits into from Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/vite-node/src/client.ts
Expand Up @@ -247,6 +247,7 @@ export class ViteNodeRunner {
debugNative(externalize)
const exports = await this.interopedImport(externalize)
mod.exports = exports
mod.evaluated = true
return exports
}

Expand Down Expand Up @@ -286,7 +287,7 @@ export class ViteNodeRunner {
},
})

Object.assign(mod, { code: transformed, exports })
Object.assign(mod, { code: transformed, exports, evaluated: false })

const __filename = fileURLToPath(url)
const moduleProxy = {
Expand Down Expand Up @@ -347,7 +348,12 @@ export class ViteNodeRunner {
columnOffset: -codeDefinition.length,
})

await fn(...Object.values(context))
try {
await fn(...Object.values(context))
}
finally {
mod.evaluated = true
}

return exports
}
Expand Down
1 change: 1 addition & 0 deletions packages/vite-node/src/types.ts
Expand Up @@ -44,6 +44,7 @@ export type CreateHotContextFunction = (runner: ViteNodeRunner, url: string) =>
export interface ModuleCache {
promise?: Promise<any>
exports?: any
evaluated?: boolean
code?: string
map?: RawSourceMap
/**
Expand Down
13 changes: 9 additions & 4 deletions packages/vitest/src/integrations/vi.ts
Expand Up @@ -247,19 +247,24 @@ class VitestUtils {
/**
* Wait for all imports to load.
* Useful, if you have a synchronous call that starts
* importing a module, that you cannot wait otherwise.
* importing a module that you cannot wait otherwise.
*/
public async dynamicImportSettled() {
const state = getWorkerState()
const promises: Promise<unknown>[] = []
for (const mod of state.moduleCache.values()) {
if (mod.promise)
if (mod.promise && !mod.evaluated)
promises.push(mod.promise)
}
if (!promises.length)
return
await Promise.allSettled(promises)
// wait until the end of the loop, so `.then` on modules called,
// wait until the end of the loop, so `.then` on modules is called,
// like in import('./example').then(...)
await new Promise(resolve => setTimeout(resolve, 1)).then(() => Promise.resolve())
// also call dynamicImportSettled again in case new imports were added
await new Promise(resolve => setTimeout(resolve, 1))
.then(() => Promise.resolve())
.then(() => this.dynamicImportSettled())
}

private _config: null | ResolvedConfig = null
Expand Down