DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
晚安云;香港 CN2 ¥15/月
雨云;给项目一台云服务器

Vitest 原生加载 mock 后,export * 导出的函数丢失

Vitest 5.0.1 的原生加载路径可能把文件路径当 URL 解析,漏掉 export * 的名称。5.0.5 已使用 file URL;工厂补出同名函数也无法修复旧的导出分析。

mock 工厂明明返回了函数,测试却报它不是函数;同文件自身导出的名称正常,只有 export * 转出的名称丢失。若 stderr 还有 ERR_INVALID_URL_SCHEME: The URL must be of scheme file,并设置了 experimental.viteModuleRunner: false,应检查原生加载的导出分析。

Vitest 5.0.1、Node 22.18、Windows 的具体组合出现这条问题。正式 5.0.5 的解析器已把目标文件路径转换为 file URL,再判断模块格式;采用更早版本时,不能只凭版本相近推断也有该处理。

工厂有返回值,导出名单仍可能漏名

关键结构是一个模块转导另一个模块,同时保留自己的函数:

// base.ts
export function fromBase() { return 'base'; }

// star.ts
export * from './base.ts';
export function own() { return 'own'; }

测试用手写工厂为 fromBase 和 own 都提供替换,但旧解析路径递归读取 base.ts 时,将磁盘路径传给需要 file URL 的模块格式判断,异常后返回空导出名单。于是 own 仍可用,fromBase 却未被正确暴露。

因此,不应反复给工厂增加一个已经存在的键,也不能把工厂改成 automock 后就视为等价修复。先保留首个解析警告,再检查工厂、真实模块和导入名称是否各自正确;普通拼错导出名仍会产生另一类缺函数错误。

采用已处理路径转换的解析器

项目允许时采用兼容的 Vitest 5.0.5,核对实际使用的 @vitest/mocker 与相关包版本一致,再通过原测试入口检查。这一版本还调整了非 JSON 文件的警告条件,避免把正常 JS、TS 一概提示成未知扩展;真正不支持的模块格式仍需另行处理。

暂不能更新,且测试不要求原生 Node 的加载语义时,可在现有配置中恢复 Vite module runner:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    experimental: { viteModuleRunner: true },
  },
});

它会改变整个测试模块的转换和加载方式,不能作为只影响一个 re-export 的局部开关。原项目若刻意测试原生解析、别名限制或插件转换缺席时的行为,应先评估这个差异。

验收覆盖模块自身导出和星号转导两类名称,并断言它们确实执行了各自 mock;同时保留不做 mock 的真实导入对照。只看到测试进程退出成功,或把相关断言删除,不能证明丢失的导出恢复。