From 632eef4037dad8712d3299650fb2f5d3ced6f671 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Wed, 24 May 2023 21:46:08 +0800 Subject: [PATCH] fix(vite-node): circular import stuck (#3418) --- examples/mocks/src/main.js | 5 +++++ examples/mocks/test/circular.spec.ts | 11 ++++++++++- packages/vite-node/src/client.ts | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/mocks/src/main.js b/examples/mocks/src/main.js index be77a608ffc..5401d983c88 100644 --- a/examples/mocks/src/main.js +++ b/examples/mocks/src/main.js @@ -1,5 +1,10 @@ import { funcA } from './A' +import { funcB } from './B' export function main() { return funcA() } + +export function mainB() { + return funcB() +} diff --git a/examples/mocks/test/circular.spec.ts b/examples/mocks/test/circular.spec.ts index 3c34b091610..e8f4651dfef 100644 --- a/examples/mocks/test/circular.spec.ts +++ b/examples/mocks/test/circular.spec.ts @@ -1,5 +1,5 @@ import { expect, test, vi } from 'vitest' -import { main } from '../src/main.js' +import { main, mainB } from '../src/main.js' import x from '../src/export-default-circle-index' vi.mock('../src/A', async () => ({ @@ -7,12 +7,21 @@ vi.mock('../src/A', async () => ({ funcA: () => 'mockedA', })) +vi.mock('../src/B', async () => ({ + ...(await vi.importActual('../src/B')), + funcB: () => 'mockedB', +})) + vi.mock('../src/export-default-circle-b') test('can import actual inside mock factory', () => { expect(main()).toBe('mockedA') }) +test('can import in top level and inside mock factory', () => { + expect(mainB()).toBe('mockedB') +}) + test('can mock a circular dependency', () => { expect(x()).toBe(undefined) }) diff --git a/packages/vite-node/src/client.ts b/packages/vite-node/src/client.ts index 29b4dc19972..6445078eb36 100644 --- a/packages/vite-node/src/client.ts +++ b/packages/vite-node/src/client.ts @@ -193,7 +193,7 @@ export class ViteNodeRunner { const getStack = () => `stack:\n${[...callstack, fsPath].reverse().map(p => ` - ${p}`).join('\n')}` // check circular dependency - if (callstack.includes(fsPath) || callstack.some(c => this.moduleCache.get(c).importers?.has(fsPath))) { + if (callstack.includes(fsPath) || callstack.some(c => this.moduleCache.get(c).importers?.has(fsPath)) || mod.importers.has(importee)) { if (mod.exports) return mod.exports }