繁体   English   中英

开玩笑:TypeError:replaceAll 不是一个函数

[英]Jest: TypeError: replaceAll is not a function

String.prototype.replaceAll()是一种有用的方法,在构建和执行时一切正常。 但是,所有 Jest 测试都失败并出现以下错误:

TypeError: replaceAll is not a function

这些是我的依赖项:

"dependencies": {
  "core-js": "^3.6.5",
  "vue": "^2.6.11",
  "vue-class-component": "^7.2.3",
  "vue-i18n": "^8.22.0",
  "vue-property-decorator": "^8.4.2",
  "vue-router": "^3.3.4",
  "vuex": "^3.5.1"
},
"devDependencies": {
  "@vue/test-utils": "^1.1.0",
  "jest-junit": "^12.0.0",
  "ts-jest": "^26.4.1",
  "typescript": "~3.9.3",
  "vue-jest": "^3.0.7",
  "vue-template-compiler": "^2.6.10"
},

我该如何解决这个问题?

这很可能发生,因为String.prototype.replaceAll没有在 Node.js 中实现(至少从v14.15.0版本开始)。

您可以使用的一种替代方法是正则表达式,如本例所示:

const str = 'foo-foo';
const regex = /foo/g; // Note the 'g' flag, which matches all occurrences of the expression

console.log(str.replace(regex, 'bar')); // 'bar-bar'

您可以在此处查看有关正则表达式的更多信息。

问题

发生这种情况是因为replaceAll是新的 function 未在所有浏览器中实现,也未在较旧的 Node.js 版本中实现,如其他答案中所述。 您可以在Can I Use中查看哪些浏览器支持它:

在此处输入图像描述

但是,您可以添加一个 polyfill 来支持旧版浏览器(如果需要),而不是使用.replace和 RegExp。 就我而言,我使用的是 Electron,所以我只需要为 Jest 做这件事。

垫片可以在这里找到

解决方案

用作浏览器的 polyfill

  1. 使用npm i string.prototype.replaceallyarn add string.prototype.replaceall作为依赖项安装;

  2. 在您的项目中添加以下代码。 它只需要在一个地方添加。

import replaceAllInserter from 'string.prototype.replaceall';

replaceAllInserter.shim();

仅在 Jest 中使用

更新 Node.js

正如评论中提到的@leonheess,您可以将 Node.js 更新到更新的版本。 您需要一个使用v8 中的 8.5 版本的版本,这是实现.replaceAll的时候。

根据Node.js 网站上提供的列表,两个版本都使用 v8 8.5,但从 Node.js 15.0.0 开始,使用的是 v8 的 8.6 版本。 因此,升级到 Node.js v15 或更高版本。

用作 polyfill

如果您只想为 Jest 解决此问题,您可以按照此问题中的说明进行操作:

  1. 使用npm i -D string.prototype.replaceallyarn add -D string.prototype.replaceall作为开发依赖项安装;

  2. 修改您的 Jest 配置,添加setupFilesAfterEnv属性,如下所示:

{
  "jest": {
    "setupFilesAfterEnv": ["<rootDir>/jestSetup.js"]
  }
}
  1. 将以下代码添加到您的jestSetup文件中:
import replaceAllInserter from 'string.prototype.replaceall';

replaceAllInserter.shim();

您也可以在 main.js 文件中的任何位置添加它

if (typeof String.prototype.replaceAll === "undefined") {
  String.prototype.replaceAll = function (match, replace) {
    return this.replace(new RegExp(match, 'g'), () => replace);
  }
}

你可以使用 Babel 来转换你的代码(到 ES5),并允许它在需要的地方注入 polyfill。

在您的情况下,使用.replaceAll方法失败,因为如其他答案中所述,测试在不支持该方法的 Node 版本上运行。

我不建议其他回答者说的那样做,因为他们只是在解决这个特定问题,但是如果您使用当前 Node 版本不支持的其他方法,您可能会遇到类似的问题。

为了保证永远不会出现此类问题, Babelcore-js一起使用。

这是此页面的重要引用: https ://jestjs.io/docs/getting-started#using-babel

babel-jest在安装 Jest 时会自动安装,如果您的项目中存在 babel 配置,它会自动转换文件。

您还需要为vue安装一个 Babel 预设,以便它会编译您特定于 vue 的文件: https ://www.npmjs.com/package/@vue/babel-preset-app

因此,在您的根文件夹中,查找Babel配置文件,或创建一个: babel.config.js (以前是.babelrc.js.json文件)。

使用此配置:

  1. 确保更新你的core-js包,并在为 Babel 配置它时明确提及次要版本(见下文)
  2. 必须激活@babel/preset-env中的useBuiltIns设置,core-js polyfills 才能工作。
  3. 还应指定targets设置,因为您的测试在 Node(而不是您的浏览器)上运行。 您还可以为此设置一个.browserlist文件。
module.exports = {
  presets: [
    ['@babel/preset-env', { 
      "corejs": "3.26", 
      "useBuiltIns": "usage", 
      "targets": { "node": "current" } 
    }],
    '@babel/preset-react'],
  plugins: [
    "@babel/plugin-transform-runtime"
  ]
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM