Native runner manual mocks drop exports re-exported with export *
Describe the bug
With experimental.viteModuleRunner: false, a manual mock of a module that re-exports with export * loses the re-exported names.
// base.ts
export function fromBase() { return 'base' }
// star.ts
export * from './base.ts'
export function own() { return 'own' }
// star.test.ts
import { fromBase, own } from './star.ts'
vi.mock(import('./star.ts'), () => ({
own: () => 'mocked-own',
fromBase: () => 'mocked-base',
}))
test('x', () => {
expect(own()).toBe('mocked-own') // ok
expect(fromBase()).toBe('mocked-base') // TypeError: fromBase is not a function
})stderr:
[module mocking] Failed to parse './base.ts' imported from .../star.ts: TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme fileCause
packages/mocker/src/node/parsers.ts, in parseModule: while collecting exports of the export * target, resolveModuleFormat(resolvedModulePath, code) is passed a filesystem path, but resolveModuleFormat(url, code) hands it to findPackageJSON, which requires a file: URL and throws. The re-export is then dropped.
Same function also warns Cannot process '...' because of unknown file extension for every non-JSON file, because the else branch runs for any extension that is not .json, including .ts and .js.
Reproduction
The three files above, experimental.viteModuleRunner: false in the config, npx vitest run.
System Info
vitest 5.0.1
node 22.18.0
win32 x64Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines
- Read the docs
- Check that there isn't already an issue that reports the same bug
- Check that this is a concrete bug
- The provided reproduction is a minimal reproducible example of the bug
I have a one-line fix with a fixture test on a branch. I'll open the PR once #11295 is resolved, since outside contributors get one open PR at a time. Claude helped me find and verify this.
Source: vitest-dev/vitest