Jest从23升级到26后遇node:stream及遍历器错误求助
Jest 23升级到26后的两个错误排查与解决
错误1:ENOENT: no such file or directory, open 'node:stream'
原因
这个问题核心是node:前缀的模块导入语法不被当前环境支持。node:是Node.js 14.13.0及以上版本才支持的核心模块导入方式,如果你的Node版本低于这个版本,或者Babel/Jest没有正确解析这种导入路径,就会出现找不到文件的错误。单独安装stream包没用,因为stream是Node核心模块,根本不需要额外安装。
解决办法
- 升级Node.js版本:直接把Node升到14.13.0或更高版本,原生支持
node:前缀导入,问题直接解决。 - 配置Jest映射规则:在
jest.config.js里添加模块映射,把node:开头的导入转换成普通核心模块导入:
module.exports = { // 其他配置... moduleNameMapper: { '^node:(.*)$': '$1' } };
- 用Babel转换导入语法:安装
babel-plugin-transform-node-imports插件,然后在.babelrc里配置:
{ "plugins": [ ["transform-node-imports", { "stream": { "default": "stream", "preventFullImport": true } // 如果还有其他node:前缀的模块,比如node:fs,也可以在这里添加 }] ] }
错误2:TypeError: Invalid attempt to spread non-iterable instance
原因
这个错误是代码里尝试对不可迭代的对象使用扩展运算符(...)导致的。比如对null、undefined,或者没有实现Symbol.iterator方法的普通对象用...扩展。升级Jest后,要么是Babel的转换规则变严格了,要么是Jest的环境模拟更贴近真实Node环境,之前被隐式忽略的问题现在暴露出来了;也可能是依赖库在新版本Jest下的返回值类型发生了变化。
解决办法
- 定位并修复出错代码:根据错误堆栈找到用了扩展运算符的代码行,检查被扩展的变量:
- 如果是普通对象,要转换成可迭代的数组再扩展,比如用
Object.values(obj)、Object.entries(obj); - 如果变量可能为
null或undefined,先做兜底处理:const arr = [...(target || [])];
- 如果是普通对象,要转换成可迭代的数组再扩展,比如用
- 调整Babel配置:确保
@babel/preset-env的配置正确,polyfill迭代器相关的内置对象。比如在.babelrc里:
{ "presets": [ ["@babel/preset-env", { "targets": { "node": "current" }, "useBuiltIns": "usage", "corejs": 3 }] ] }
- 同步依赖版本:确保
babel-jest的版本和Jest版本完全一致(比如Jest 26.x对应babel-jest 26.x),避免版本不兼容导致的语法转换问题; - 修正测试模拟:如果是测试中模拟的函数返回了不可迭代对象,调整模拟返回值为可迭代类型,或者给对象添加
Symbol.iterator方法:
jest.mock('./your-module', () => ({ getList: () => ({ [Symbol.iterator]: function* () { yield 'item1'; yield 'item2'; } }) }));
参考配置示例
package.json(核心依赖)
{ "devDependencies": { "jest": "^26.6.3", "babel-jest": "^26.6.3", "@babel/core": "^7.15.8", "@babel/preset-env": "^7.15.8", "babel-plugin-transform-node-imports": "^2.0.0" } }
.babelrc
{ "presets": [ ["@babel/preset-env", { "targets": { "node": "12" }, "useBuiltIns": "usage", "corejs": 3 }] ], "plugins": [ ["transform-node-imports", { "stream": { "default": "stream", "preventFullImport": true } }] ] }
内容的提问来源于stack exchange,提问作者nari447
相关产品推荐
相关产品推荐

