Skip to content

Commit

Permalink
fix(vite-node): circular deps detection
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Mar 23, 2022
1 parent c9f53f2 commit 873d89a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
23 changes: 11 additions & 12 deletions packages/vite-node/src/client.ts
Expand Up @@ -3,7 +3,7 @@ import { fileURLToPath, pathToFileURL } from 'url'
import vm from 'vm'
import { dirname, extname, isAbsolute, resolve } from 'pathe'
import { isNodeBuiltin } from 'mlly'
import { isPrimitive, normalizeId, slash, toFilePath } from './utils'
import { isPrimitive, normalizeModuleId, normalizeRequestId, slash, toFilePath } from './utils'
import type { ModuleCache, ViteNodeRunnerOptions } from './types'

export const DEFAULT_REQUEST_STUBS = {
Expand All @@ -25,11 +25,7 @@ export const DEFAULT_REQUEST_STUBS = {

export class ModuleCacheMap extends Map<string, ModuleCache> {
normalizePath(fsPath: string) {
return fsPath
.replace(/\\/g, '/')
.replace(/^\/@fs\//, '/')
.replace(/^file:\//, '/')
.replace(/^\/+/, '/')
return normalizeModuleId(fsPath)
}

set(fsPath: string, mod: Partial<ModuleCache>) {
Expand Down Expand Up @@ -74,8 +70,9 @@ export class ViteNodeRunner {
return await this.cachedRequest(id, [])
}

/** @internal */
async cachedRequest(rawId: string, callstack: string[]) {
const id = normalizeId(rawId, this.options.base)
const id = normalizeRequestId(rawId, this.options.base)
const fsPath = toFilePath(id, this.root)

if (this.moduleCache.get(fsPath)?.promise)
Expand All @@ -87,8 +84,9 @@ export class ViteNodeRunner {
return await promise
}

/** @internal */
async directRequest(id: string, fsPath: string, callstack: string[]) {
callstack = [...callstack, id]
callstack = [...callstack, normalizeModuleId(id)]
const request = async(dep: string) => {
// probably means it was passed as variable
// and wasn't transformed by Vite
Expand All @@ -97,10 +95,11 @@ export class ViteNodeRunner {
dep = resolvedDep?.id?.replace(this.root, '') || dep
}

if (callstack.includes(dep)) {
if (!this.moduleCache.get(dep)?.exports)
throw new Error(`[vite-node] Circular dependency detected\nStack:\n${[...callstack, dep].reverse().map(p => `- ${p}`).join('\n')}`)
return this.moduleCache.get(dep)!.exports
if (callstack.includes(normalizeModuleId(dep))) {
const depExports = this.moduleCache.get(dep)?.exports
if (depExports)
return depExports
throw new Error(`[vite-node] Circular dependency detected\nStack:\n${[...callstack, dep].reverse().map(p => `- ${p}`).join('\n')}`)
}
return this.cachedRequest(dep, callstack)
}
Expand Down
10 changes: 9 additions & 1 deletion packages/vite-node/src/utils.ts
Expand Up @@ -8,7 +8,7 @@ export function slash(str: string) {
return str.replace(/\\/g, '/')
}

export function normalizeId(id: string, base?: string): string {
export function normalizeRequestId(id: string, base?: string): string {
if (base && id.startsWith(base))
id = `/${id.slice(base.length)}`

Expand All @@ -25,6 +25,14 @@ export function normalizeId(id: string, base?: string): string {
.replace(/\?+$/, '') // remove end query mark
}

export function normalizeModuleId(id: string) {
return id
.replace(/\\/g, '/')
.replace(/^\/@fs\//, '/')
.replace(/^file:\//, '/')
.replace(/^\/+/, '/')
}

export function isPrimitive(v: any) {
return v !== Object(v)
}
Expand Down

0 comments on commit 873d89a

Please sign in to comment.