Skip to content

Commit 1a961d9

Browse files
authoredOct 10, 2022
fix(ssr): handle parallel hookNodeResolve (#10401)
1 parent 3a87593 commit 1a961d9

File tree

1 file changed

+39
-27
lines changed

1 file changed

+39
-27
lines changed
 

‎packages/vite/src/node/ssr/ssrModuleLoader.ts

+39-27
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ async function instantiateModule(
226226
return Object.freeze(ssrModule)
227227
}
228228

229+
// `nodeImport` may run in parallel on multiple `ssrLoadModule` calls.
230+
// We keep track of the current importing count so that the first import
231+
// would `hookNodeResolve`, and the last import would `unhookNodeResolve`.
232+
let importingCount = 0
233+
let unhookNodeResolve: ReturnType<typeof hookNodeResolve> | undefined
234+
229235
// In node@12+ we can use dynamic import to load CJS and ESM
230236
async function nodeImport(
231237
id: string,
@@ -250,34 +256,36 @@ async function nodeImport(
250256
return resolved.id
251257
}
252258

253-
// When an ESM module imports an ESM dependency, this hook is *not* used.
254-
const unhookNodeResolve = hookNodeResolve(
255-
(nodeResolve) => (id, parent, isMain, options) => {
256-
// Use the Vite resolver only for bare imports while skipping
257-
// any absolute paths, built-in modules and binary modules.
258-
if (
259-
!bareImportRE.test(id) ||
260-
path.isAbsolute(id) ||
261-
isBuiltin(id) ||
262-
id.endsWith('.node')
263-
) {
264-
return nodeResolve(id, parent, isMain, options)
265-
}
266-
if (parent) {
267-
let resolved = viteResolve(id, parent.id)
268-
if (resolved) {
269-
// hookNodeResolve must use platform-specific path.normalize
270-
// to be compatible with dynamicImport (#6080)
271-
resolved = path.normalize(resolved)
259+
if (importingCount === 0) {
260+
// When an ESM module imports an ESM dependency, this hook is *not* used.
261+
unhookNodeResolve = hookNodeResolve(
262+
(nodeResolve) => (id, parent, isMain, options) => {
263+
// Use the Vite resolver only for bare imports while skipping
264+
// any absolute paths, built-in modules and binary modules.
265+
if (
266+
!bareImportRE.test(id) ||
267+
path.isAbsolute(id) ||
268+
isBuiltin(id) ||
269+
id.endsWith('.node')
270+
) {
271+
return nodeResolve(id, parent, isMain, options)
272272
}
273-
return resolved
273+
if (parent) {
274+
let resolved = viteResolve(id, parent.id)
275+
if (resolved) {
276+
// hookNodeResolve must use platform-specific path.normalize
277+
// to be compatible with dynamicImport (#6080)
278+
resolved = path.normalize(resolved)
279+
}
280+
return resolved
281+
}
282+
// Importing a CJS module from an ESM module. In this case, the import
283+
// specifier is already an absolute path, so this is a no-op.
284+
// Options like `resolve.dedupe` and `mode` are not respected.
285+
return id
274286
}
275-
// Importing a CJS module from an ESM module. In this case, the import
276-
// specifier is already an absolute path, so this is a no-op.
277-
// Options like `resolve.dedupe` and `mode` are not respected.
278-
return id
279-
}
280-
)
287+
)
288+
}
281289

282290
let url: string
283291
if (id.startsWith('node:') || isBuiltin(id)) {
@@ -299,10 +307,14 @@ async function nodeImport(
299307
}
300308

301309
try {
310+
importingCount++
302311
const mod = await dynamicImport(url)
303312
return proxyESM(mod)
304313
} finally {
305-
unhookNodeResolve()
314+
importingCount--
315+
if (importingCount === 0) {
316+
unhookNodeResolve?.()
317+
}
306318
}
307319
}
308320

0 commit comments

Comments
 (0)
Please sign in to comment.