SyntaxError: Unexpected token export while running tests in Jest with components having amcharts4

SyntaxError: Unexpected token export while running tests in Jest with components having amcharts4

出现错误:运行 在 Jest 中使用具有 amcharts4

的组件进行测试时出现意外的令牌导出
 export { System, system } from "./.internal/core/System";
    ^^^^^^

    SyntaxError: Unexpected token export

    > 1 | import * as am4core from "@amcharts/amcharts4/core";
        | ^
      2 | import * as am4charts from "@amcharts/amcharts4/charts";
      3 | import * as am4maps from "@amcharts/amcharts4/maps";
      4 | import am4geodata_worldLow from "@amcharts/amcharts4-geodata/worldLow";

“开玩笑”:“24.9.0”
"@amcharts/amcharts4": "^4.10.19"
“打字稿”:“^3.9.5”

以下是 package.json 文件中的 jest 配置:(为项目使用 create-react-app 并将其弹出)

"jest": {
    "roots": [
      "<rootDir>/src"
    ],
    
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,ts,tsx}",
      "!src/**/*.d.ts"
    ],
    "setupFiles": [
      "react-app-polyfill/jsdom",
      "<rootDir>\src\__mocks__\dom.js",
      "<rootDir>\src\__mocks__\reactrouter.js"
    ],
    "setupFilesAfterEnv": [
      "@testing-library/jest-dom/extend-expect"
    ],
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
      "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
    ],
    "testEnvironment": "jest-environment-jsdom-fourteen",
    "transform": {
      "^.+\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
      "^.+\.css$": "<rootDir>/config/jest/cssTransform.js",
      "^(?!.*\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!@amcharts/amcharts4/)",
      "^.+\.module\.(css|sass|scss)$"
    ],
    "modulePaths": [
      "<rootDir>/src/",
      "<rootDir>/node_modules/"
    ],
    "moduleNameMapper": {
      "\.(css|scss)$": "<rootDir>/src/__mocks__/styleMock.js"
    },
    "moduleFileExtensions": [
      "web.js",
      "js",
      "web.ts",
      "ts",
      "web.tsx",
      "tsx",
      "json",
      "web.jsx",
      "jsx",
      "node"
    ],
    "watchPlugins": [
      "jest-watch-typeahead/filename",
      "jest-watch-typeahead/testname"
    ]
}

原因: babel-jest 使用了根据要转换的文件的位置加载的 babel 配置。弹出 create-react-app 后你的 package.json 可能包含:

"babel": {
  "presets": [
    "react-app"
  ]
}

这使得 import/export 语句适用于您的文件,但是 @amcharts/amcharts4 在其 package.json 中没有该设置,也没有 .babelrc ,因此没有 import/export 转变发生。

解决方案:您可以更新 Jest 配置,以更具体的方式转换 @amcharts:

  1. 添加相关的babel插件:npm install -D @babel/plugin-transform-modules-commonjs
  2. 更新 package.json 中的 jest 配置 - 将 @amcharts 转换重定向到自定义转换器。 (我还更改了 transformIgnorePatterns 以便它们适用于 Windows。)
"transform": {
  "@amcharts[/\\].+\.(js|jsx|ts|tsx)$": "<rootDir>/config/jest/babelTransformImportExport.js",
  "^.+\.(js|jsx|ts|tsx)$": "babel-jest",
  "^.+\.css$": "<rootDir>/config/jest/cssTransform.js",
  "^(?!.*\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
  "node_modules[/\\](?!@amcharts[/\\]amcharts4[/\\])",
  "^.+\.module\.(css|sass|scss)$"
],

  1. 创建 config/jest/babelTransformImportExport.js:
const babelJest = require("babel-jest");

module.exports = babelJest.createTransformer({
  plugins: [require.resolve("@babel/plugin-transform-modules-commonjs")],
  babelrc: false,
  configFile: false,
});

测试现在应该 运行。

编辑: 正如 Subrato Patnaik 提到的(using amcharts with jest), amcharts use APIs such as SVGPathElement which aren't yet available in Jest test environment (JSDOM - issue #2128). In other words, your tests won't probably work, if you're using standard mounting. But they might work if you are using e.g. enzyme 及其浅渲染。

如果你不使用enzyme或者它不起作用,那么不得已,你可以尝试简单地用极简的方式定义缺失的API,看看是否足够:

  1. 将 jest 配置中的 setupFiles 更改为:
"setupFiles": [
  "react-app-polyfill/jsdom",
  "<rootDir>/config/jest/setup.js"
],
  1. 创建 config/jest/setup.js:
class SVGGraphicsElement extends SVGElement {}
class SVGGeometryElement extends SVGGraphicsElement {}
class SVGPathElement extends SVGGeometryElement {}

Object.assign(global, {
  SVGGraphicsElement,
  SVGGeometryElement,
  SVGPathElement,
});

PS: 如果您使用的是 pnpm 而不是 npm/yarn,那么您需要将 transformIgnorePatterns 更新为:

"node_modules[/\\](?!(|\.pnpm[/\\]@amcharts.*node_modules[/\\])@amcharts[/\\]amcharts4[/\\])",

否则旧的正则表达式将匹配(并因此忽略)诸如 node_modules/.pnpm/@amcharts+amcharts4@4.10.21/node_modules/@amcharts/amcharts4/core.js

的路径