React Jest 测试无法使用 ts-jest 运行 - 导入文件上出现意外令牌
Posted
技术标签:
【中文标题】React Jest 测试无法使用 ts-jest 运行 - 导入文件上出现意外令牌【英文标题】:React Jest test fails to run with ts-jest - Unexpected token on imported file 【发布时间】:2020-01-25 13:20:55 【问题描述】:我有一个 TSX 文件的测试,该文件写在一个 JSX 文件中,但由于意外令牌而无法运行:
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 编写的测试,用于运行 JSX 文件。我正在使用 React 测试库,但我认为这不是问题,因为文件导入测试失败。
堆栈跟踪:
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)`
笑话配置:
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 吗? @AbishekAditya 是的,它已安装。 嗯,让我尝试引导一个简单的项目并回复您 【参考方案1】:在搞砸了这么久之后,问题似乎与 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 - Cannot read property createElement of undefined
是在使用 TypeScript 时引起的:https://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】:看来您必须将其添加到您的 Jest 配置文件中
"transform":
"\\.tsx?$": "ts-jest",
"\\.jsx?$": "babel-jest", // if you have jsx tests too
,
"globals":
"ts-jest":
"tsConfig": pathToYourTsConfigFile
更多信息在这里:https://jestjs.io/docs/en/configuration.html#transform-object-string-pathtotransformer-pathtotransformer-object 和这里https://kulshekhar.github.io/ts-jest/user/config/
【讨论】:
现在得到一个稍微不同的错误。我更新了上面的代码示例,以反映我修改后的代码和错误。【参考方案3】:此后,我发现了针对 lodash-es 特定情况的另一种替代方法。您可以使用普通的 lodash 库,只需导入您需要的函数。然后,您无需使用 transformIgnorePatterns 即可获得 lodash-es 包的好处。
例如:
import camelCase from 'lodash/camelCase';
camelCase('my string');
【讨论】:
以上是关于React Jest 测试无法使用 ts-jest 运行 - 导入文件上出现意外令牌的主要内容,如果未能解决你的问题,请参考以下文章
react-native, jest, ts-jest: ReferenceError: React is not defined
无法使用 ts-jest 转换 node_modules 中的文件夹
使用 React、Typescript 和 ES6 进行 Jest 测试