Node v18环境下Mocha运行测试报structuredClone未定义如何解决
问题根因
Mocha本身不内置独立的Node运行时,所有测试代码都直接运行在你执行mocha命令时对应的当前Node进程环境中,你项目使用的mocha v10.0.0本身完全兼容Node 18,不存在版本兼容问题。出现structuredClone is not defined只有两个核心原因:
- 执行测试时的Node实际版本低于17.0.0:
structuredClone是Node 17.0.0才正式加入全局对象的API,Node 16及更早版本没有该全局方法 - 全局对象被第三方依赖覆盖:你项目中依赖了
jsdom@20.0.0,该版本的jsdom提供的浏览器环境模拟对象默认不包含structuredClone实现,如果测试代码中把jsdom的window对象全量挂载到全局,会覆盖Node原生的全局API。
排查步骤
- 先确认运行时Node版本
在测试用例的最顶部添加一行代码:
执行测试后看终端输出,如果版本号低于v17.0.0,就是运行时版本不对。console.log('当前测试运行Node版本:', process.version)
常见的版本不一致场景:- VS Code集成终端默认加载的是系统全局Node版本,和你手动切换的v18环境不互通(比如用nvm管理版本时,新开终端不会自动切到项目指定版本)
- 全局安装的mocha绑定了低版本Node,直接调用全局
mocha命令时会用低版本Node启动进程
- 如果输出版本是v18.x,检查测试入口的jsdom初始化代码,看是否存在类似
globalThis = window或者Object.assign(globalThis, window)的全量赋值逻辑,这类操作会覆盖Node原生全局方法。
解决方案
- 统一运行时版本:
- 项目根目录新建
.nvmrc文件写入18,进入项目目录后执行nvm use自动切到Node 18 - 不要使用全局安装的mocha,将package.json中的test脚本修改为调用本地依赖的mocha,例如:
执行"scripts": { "test": "npx mocha --require ts-node/register test/**/*.ts" }npm test时npx会优先调用本地node_modules中的mocha,和当前终端的Node版本绑定。
- 项目根目录新建
- 修复jsdom全局污染:
不要全量把jsdom的window对象挂载到全局,只挂载测试需要的特定API即可;如果必须全量挂载,可以升级jsdom到v22及以上版本,该版本后jsdom已内置structuredClone实现。 - 临时兼容方案:
如果暂时无法统一运行时版本,可以在测试入口文件最顶部添加polyfill,普通对象场景可以用简易实现:
如果需要支持循环引用、特殊类型拷贝,可以安装if (typeof globalThis.structuredClone !== 'function') { globalThis.structuredClone = (val) => JSON.parse(JSON.stringify(val)) }@ungap/structured-clone包做完整polyfill。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

