React Jest测试在使用ts-jest时无法运行 - 导入文件中出现意外的标记

10

我有一个测试,是在一个JSX文件中编写的针对TSX文件的测试,但由于出现了意外的标记(unexpected token),导致无法运行。

Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

我有另一个用JSX编写的测试,测试文件能够正常运行。我使用React Testing Library进行测试,但我认为问题不在此处,因为该测试在文件导入时失败。

堆栈跟踪:

 export { default as add } from './add.js';
^^^^^^

SyntaxError: Unexpected token export

  1 | import React from 'react';
> 2 | import { debounce } from 'lodash-es';
    | ^
  3 | 
  4 | interface Props {
  5 |   bodyContent?: string

  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
  at Object.<anonymous> (components/tsx/TestComponentTSX.tsx:2:1)`

Jest配置:

module.exports = {
  moduleDirectories: [
    'node_modules'
  ],
  transform: {
    "\\.tsx?$": "ts-jest",
    "\\.jsx?$": "babel-jest",
  },
  globals: {
    "ts-jest": {
      "tsConfig": '<rootDir>/tsconfig.json'
    }
  }
}

TS 配置:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "allowSyntheticDefaultImports": true
  }
}

TestComponentTSX.tsx

import React from 'react';
import { debounce } from 'lodash-es';

interface Props {
  bodyContent?: string
}

function TestComponentTSX(props: Props) {

  const clickHandler = (): void => {
    console.log('I am being clicked!');
  };

  const debouncedClickHandler = debounce(clickHandler, 400)

  return (
    <div>
      <h1>Hello World!</h1>
      <p>{props.bodyContent || 'World...'}</p>
      <button type="button" onClick={debouncedClickHandler}>Click me!</button>
    </div>
  )
}

export default TestComponentTSX;

TestComponentTSX.test.tsx

import React from 'react';
import { render } from '@testing-library/react';
import TestComponentTSX from './TestComponentTSX';

describe('The TSX component is testable', () => {
  test('The component renders', () => {
    // Arrange
    const { getByText } = render(
      <TestComponentTSX />
    );

    // Act
    // Do something

    // Assert
    expect(getByText('Hello World!'));
  })
});

package.json

{
  "name": "jesttypescriptreact",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build-dev": "cross-env NODE_ENV=development webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash-es": "^4.17.15",
    "react": "^16.10.1",
    "react-dom": "^16.10.1"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/plugin-proposal-class-properties": "^7.5.5",
    "@babel/plugin-proposal-object-rest-spread": "^7.6.2",
    "@babel/preset-env": "^7.6.2",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.6.0",
    "@testing-library/react": "^9.2.0",
    "@types/jest": "^24.0.18",
    "@types/lodash-es": "^4.17.3",
    "@types/react-dom": "^16.9.1",
    "babel-loader": "^8.0.6",
    "cross-env": "^6.0.0",
    "jest": "^24.9.0",
    "ts-jest": "^24.1.0",
    "ts-loader": "^6.2.0",
    "typescript": "^3.6.3",
    "webpack": "^4.41.0",
    "webpack-cli": "^3.3.9"
  }
}

你在开发环境依赖中安装了 ts-jest 吗? - Abishek Aditya
@AbishekAditya 是的,已经安装好了。 - Antfish
嗯,让我尝试引导一个简单的项目,然后再回复你。 - Abishek Aditya
3个回答

6
经过漫长的尝试,看起来问题似乎与 lodash-es 包和 Jest 不支持 ES 模块有关。在这里提到了这一点:https://github.com/facebook/jest/issues/4842 在 @CarlosCrespo 的答案基础上,我还需要告诉 babel 在使用 transformIgnorePatterns 属性进行转译时不要忽略 lodash-es,从而得到以下结果:
jest.config.js
module.exports = {
  moduleDirectories: [
    'node_modules'
  ],
  transform: {
    "\\.tsx?$": "ts-jest",
    "\\.jsx?$": "babel-jest", // if you have jsx tests too
  },
  globals: {
    "ts-jest": {
      "tsConfig": '<rootDir>/tsconfig.json'
    }
  },
  transformIgnorePatterns: [
    "[/\\\\]node_modules[/\\\\](?!lodash-es/).+\\.js$"
  ],
}

除此之外,我还需要在出现另一个错误时更新我的 tsconfig.json 文件 — 当我在使用 TypeScript 时遇到了错误 Cannot read property createElement of undefinedhttps://github.com/testing-library/react-testing-library/issues/374

tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "lib": ["dom", "esnext"],
    "module": "esnext",
    "target": "es5",
    "jsx": "react",
    "esModuleInterop": true,
    "allowJs": true,
    "allowSyntheticDefaultImports": true
  },
  "exclude": ["node_modules"]
}

2

现在出现了稍微不同的错误。我已经更新了我的代码示例以反映我的修改后的代码和错误。 - Antfish

0

针对lodash-es的特定情况,我后来发现了另一种替代方法。您可以使用普通的lodash库并仅导入您需要的函数。这样,您就可以享受lodash-es软件包的好处,而无需使用transformIgnorePatterns。

E.g:

import camelCase from 'lodash/camelCase';

camelCase('my string');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接