From 6dd7f53588d03688b7ade05dbc5e0c314beb962e Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 29 Mar 2022 17:35:57 +0800 Subject: [PATCH] feat(vite-node): support debug flag to emit additional info --- packages/vite-node/src/client.ts | 47 +++++++++++++++++++++++++------- packages/vite-node/src/types.ts | 1 + 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/packages/vite-node/src/client.ts b/packages/vite-node/src/client.ts index 29cb4288a5ab..6cf320995350 100644 --- a/packages/vite-node/src/client.ts +++ b/packages/vite-node/src/client.ts @@ -51,6 +51,8 @@ export class ModuleCacheMap extends Map { export class ViteNodeRunner { root: string + debug: boolean + /** * Holds the cache of modules * Keys of the map are filepaths, or plain package names @@ -58,8 +60,9 @@ export class ViteNodeRunner { moduleCache: ModuleCacheMap constructor(public options: ViteNodeRunnerOptions) { - this.root = options.root || process.cwd() - this.moduleCache = options.moduleCache || new ModuleCacheMap() + this.root = options.root ?? process.cwd() + this.moduleCache = options.moduleCache ?? new ModuleCacheMap() + this.debug = options.debug ?? (typeof process !== 'undefined' ? !!process.env.VITE_NODE_DEBUG : false) } async executeFile(file: string) { @@ -85,9 +88,13 @@ export class ViteNodeRunner { } /** @internal */ - async directRequest(id: string, fsPath: string, callstack: string[]) { - callstack = [...callstack, normalizeModuleId(id)] + async directRequest(id: string, fsPath: string, _callstack: string[]) { + const callstack = [..._callstack, normalizeModuleId(id)] const request = async(dep: string) => { + const getStack = () => { + return `stack:\n${[...callstack, dep].reverse().map(p => `- ${p}`).join('\n')}` + } + // probably means it was passed as variable // and wasn't transformed by Vite if (this.options.resolveId && this.shouldResolveId(dep)) { @@ -95,13 +102,27 @@ export class ViteNodeRunner { dep = resolvedDep?.id?.replace(this.root, '') || dep } - 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')}`) + let debugTimer: any + if (this.debug) + debugTimer = setTimeout(() => this.debugLog(() => `module ${dep} takes over 2s to load.\n${getStack()}`), 2000) + + try { + if (callstack.includes(normalizeModuleId(dep))) { + this.debugLog(() => `circular dependency, ${getStack()}`) + const depExports = this.moduleCache.get(dep)?.exports + if (depExports) + return depExports + throw new Error(`[vite-node] Failed to resolve circular dependency, ${getStack()}`) + } + + const mod = await this.cachedRequest(dep, callstack) + + return mod + } + finally { + if (debugTimer) + clearTimeout(debugTimer) } - return this.cachedRequest(dep, callstack) } const requestStubs = this.options.requestStubs || DEFAULT_REQUEST_STUBS @@ -212,6 +233,12 @@ export class ViteNodeRunner { hasNestedDefault(target: any) { return '__esModule' in target && target.__esModule && 'default' in target.default } + + private debugLog(msg: () => string) { + if (this.debug) + // eslint-disable-next-line no-console + console.log(`[vite-node] ${msg()}`) + } } function proxyMethod(name: 'get' | 'set' | 'has' | 'deleteProperty', tryDefault: boolean) { diff --git a/packages/vite-node/src/types.ts b/packages/vite-node/src/types.ts index 92a15e6c2d8c..06666b4c2cb6 100644 --- a/packages/vite-node/src/types.ts +++ b/packages/vite-node/src/types.ts @@ -47,6 +47,7 @@ export interface ViteNodeRunnerOptions { moduleCache?: ModuleCacheMap interopDefault?: boolean requestStubs?: Record + debug?: boolean } export interface ViteNodeResolveId {