如何修复 Jest 中的意外 Token 错误

2025-06-04

如何修复 Jest 中的意外 Token 错误

我最近遇到了一个棘手的问题,花了大半天时间才解决。所以我把我的解决方案分享出来,希望对大家有所帮助。


替代文本

问题

我创建了一个使用现代 JavaScript 的 NPM 包。我所说的“现代”是指符合 ES2015 标准的 JavaScript(说实话,我觉得它并不算……现代,但 NPM 和 Jest 似乎还停留在 2013 年 CommonJS 的辉煌时期——所以,随便吧……)。我拒绝用老套的语言require()module.export所有其他过时的约定来编写我的包。都 2021 年了,该死的。Babel 并不是什么尖端技术。我应该能够以一种与我应用程序中其他代码一致的方式编写我的包。

因为我编写这个包是为了公共/分布式使用,所以我觉得对其进行良好的单元测试非常重要。作为一名“React 人”,我倾向于默认使用 Jest。但通常情况下,当我使用 Jest 时,我会在自己维护的运行时环境中测试一小批代码。当我这样做时,Jest 运行得很好。

但这次,我正在测试我自己的 NPM 包,它会导入我的一些其他 NPM 包。换句话说,我使用 Jest 测试一个包含“现代” JavaScript 的包,而这个包又会导入另一个包含“现代” JavaScript 的包。而 Jest 对此很不满意,一点儿也不满意。

问题在于 Jest 只处理 CommonJS 风格的代码。因此,要运行 Jest 测试,首先需要使用 Babel 进行转译。如果转译不正确,就会出现如下错误:



Jest encountered an unexpected token


Enter fullscreen mode Exit fullscreen mode

根据您的设置,您可能会在代码文件的第一行看到错误,或者在代码尝试处理 JSX 时看到错误。我在第一行看到了错误,因为第一行几乎总是被一个import语句占据——而 CommonJS 中没有import语句。


替代文本

头痛

如果你在 Google 上搜索“jest unknown token”,你会发现有几个迹象表明这是一个非常严重的问题:

  1. 关于这个问题有很多讨论 - 在 Stack Overflow 上和其他地方。

  2. 这些帖子跨越了好几年——这意味着这个问题会反复出现在人们面前。

  3. 很多帖子都很。这个问题不是那种能快速给出答案就能解决的问题。

  4. 从这些帖子中可以明显看出,这不是典型的菜鸟问题。有些发帖的人似乎对 Jest / React / Babel / TypeScript 等配置的各个方面都很了解。

  5. 似乎没有一个通用的答案。帖子里充斥着一个人发的帖子,比如“我是这样解决的。”——然后其他几个人也说他们做了完全一样的事情……但问题还是没有解决。

  6. 所有建议的答案似乎都与环境相关。有时您需要使用transformIgnorePatters- 但在其他版本中,这没有任何作用。在 Windows 上工作?您可能需要cross-env在解决方案中的某个地方使用。或者可能是win-node-env。或者可能是env-cmd。或者可能是windows-environment。如果您使用 React,您可能需要与 Vue 不同的解决方案。如果您使用 TypeScript,则这两个解决方案可能都不同。您可能需要一个正确配置的.babelrc文件 - 但也许您需要将其更改为babel.config.json


仅供参考,我甚至在 Dev.to 上找到了几篇提出解决方案的文章 - 但对我没有任何帮助。

在开始我的解决方案之前,我得说一句,依我拙见,Babel 和/或 Jest 在这方面确实存在问题。当你看到这么多人为某件事苦苦挣扎这么久——而这些人似乎都知道自己在做什么——嗯……这个过程确实需要一些优化。


替代文本

免责声明

如果你还没搞明白,Babel/WebPack/Jest/React 的配置有时会让我感到困惑。没错,这话出自一个几十年来一直深耕于此的人之口。有些人真的很喜欢解决这类问题——但这些问题只会让我。我最终花了太多时间去处理一个我其实并不太在意的问题,这让我无法专心写代码。

考虑到这一点,我绝对知道如何针对每种配置(甚至大多数配置)解决这个问题。我只知道我最终找到了解决办法。所以这篇文章对你来说可能和过去几天我浏览过的其他文章一样没用。但希望它能帮节省一点时间。

正如我已经提到的,这些解决方案似乎与环境高度相关。所以你应该知道我正在一台 Windows 10 机器上工作,并在本地安装了 Node v14.2.0、NPMv6.14.4和 Jest v26.6.3


替代文本

解决方案 #1 - 独立的 JS 项目

package.json(节选)



{
  "name": "@toolz/allow",
  "main": "src/allow.js",
  "scripts": {
    "test": "jest --transformIgnorePatterns \"node_modules/(?!@toolz/allow)/\" --env=jsdom"
  },
  "type": "module",
  "devDependencies": {
    "@babel/cli": "^7.13.0",
    "@babel/core": "^7.13.1",
    "@babel/node": "^7.10.5",
    "@babel/plugin-transform-modules-commonjs": "^7.13.0",
    "@babel/preset-env": "^7.11.0",
    "@babel/preset-react": "^7.12.13",
    "babel-jest": "^26.6.3",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-preset-jest": "^26.6.2",
    "jest": "^26.6.3",
    "jest-cli": "^26.6.3",
  },
  "dependencies": {
    "@toolz/is-a-regular-object": "^1.0.1"
  }
}


Enter fullscreen mode Exit fullscreen mode

特别注意节点。项目scripts: test名称)在括号里。另外,直到我将值设置为 时,它起作用。我觉得我并不需要节点里的所有东西。但你知道吗?它现在就可以正常工作了——所以我不会再动它了。@toolz/allowenvjsdomdevDependencies

babel.config.json



{
  "presets": [
    "@babel/preset-env"
  ]
}


Enter fullscreen mode Exit fullscreen mode

注意:不是 .babelrc。在这个特定的设置中,我似乎需要将文件设置为babel.config.json

通过这些设置,我现在可以运行,npm test并且它可以正确运行我的测试 - 包括那些需要的import测试@toolz/is-a-regular-object


解决方案 #2 - React 项目(带有create-react-app

package.json(节选)



{
  "name": "@toolz/allow-react",
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.7.2",
    "@toolz/allow": "^1.0.1",
    "@toolz/is-a-regular-object-react": "^1.0.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.2",
    "web-vitals": "^1.1.0"
  },
  "scripts": {
    "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!@toolz/allow-react)/\" --env=jsdom"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "devDependencies": {
    "@babel/plugin-transform-modules-commonjs": "^7.12.13",
    "babel-jest": "^26.6.3"
  }
}


Enter fullscreen mode Exit fullscreen mode

与应用程序一致create-react-app,此项目中没有.babelrcbabel.config.json文件。我需要的一切都在这里package.json。现在可以使用 运行所有测试,包括来自其他 ES2015 语法项目的npm test测试。import

正如我试图解释的那样,我不知道这在你的项目中是否有效。哎,可能不行。但也许这些配置能帮到一些人?

文章来源:https://dev.to/bytebodger/how-i-fixed-the-unexpected-token-error-in-jest-4o1j
PREV
如何招聘程序员
NEXT
开发人员拖延