为什么Jest
在简单的导入语句上失败并显示“意外令牌*” ...
Admin@Admin-PC MINGW32 /d/project (master)
$ npm run test
> MyApp@0.0.1 test D:\project
> jest
FAIL __tests__/App-test.tsx
? 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".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
D:\project\node_modules\react-navigation-tabs\src\navigators\createBottomTabNavigator.js:3
import * as React from 'react';
^
SyntaxError: Unexpected token *
14 | // );
15 |
> 16 | export default createBottomTabNavigator({
| ^
17 | map: {
18 | screen: MapView,
19 | navigationOptions: {
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
at Object.get createBottomTabNavigator [as createBottomTabNavigator] (node_modules/react-navigation-tabs/src/index.js:9:12)
at Object.<anonymous> (src/app/main.view.tsx:16:16)
FAIL src/component/reinput/example/__tests__/index.ios.js (19.352s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
FAIL src/component/reinput/example/__tests__/index.android.js (19.365s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
Test Suites: 3 failed, 3 total
Tests: 2 failed, 2 total
Snapshots: 0 total
Time: 22.774s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! MyApp@0.0.1 test: `jest`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the MyApp@0.0.1 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Admin\AppData\Roaming\Roaming\npm-cache\_logs\2019-04-22T11_52_36_984Z-debug.log
package.json
文件:{
"name": "MyApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.4",
"react-native-gesture-handler": "^1.1.0",
"react-native-reanimated": "^1.0.1",
"react-native-splash-screen": "^3.2.0",
"react-navigation": "^3.8.1",
"react-navigation-tabs": "^2.1.1"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/runtime": "^7.4.3",
"@types/jest": "^24.0.11",
"@types/react": "^16.8.13",
"@types/react-dom": "^16.8.4",
"@types/react-native": "^0.57.46",
"@types/react-test-renderer": "^16.8.1",
"babel-jest": "^24.7.1",
"jest": "^24.7.1",
"metro-react-native-babel-preset": "^0.53.1",
"react-test-renderer": "16.8.3",
"typescript": "^3.4.3"
},
"jest": {
"preset": "react-native"
}
}
babel.config.js
文件:module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
jest.config.js
文件:module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
注意:我正在使用react-native
类型脚本模板,例如react-native init MyApp --template typescript
答案 0 :(得分:10)
如前所述,有些模块需要转译,而有些则不需要。 这是我在很多项目中使用的正则表达式
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|@react-native-community/(.*)|@react-navigation/(.*)|bs-platform|(@[a-zA-Z]+/)?(bs|reason|rescript)-(.*)+)"
]
}
它适用于大多数常见的反应本地事物,并且还包含一个特定的程序包(此处为bs-platform
),例如以前的模式未捕获的程序包。
答案 1 :(得分:4)
我在React + Typescript应用程序上遇到了类似的问题。
我犯的第一个错误是将jest.config.js
定义为jest.config.ts
在Node v12.latest上运行
然后对我有用的配置如下:
// jest.config.js
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["./src"],
transform: { "\\.ts$": ["ts-jest"] },
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
globals: {
"ts-jest": {
tsConfig: {
// allow js in typescript
allowJs: true,
},
},
},
};
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "."
},
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
// package.json
"devDependencies": {
"@types/jest": "^26.0.5",
"jest": "^26.1.0",
"ts-jest": "^26.1.3"
}
答案 2 :(得分:2)
某些react-native
库附带未编译的ES6代码。
ES6代码需要先编译,然后才能由Jest
运行。
有关Testing React Native Apps的Jest
文档包括有关compiling dependencies that don't ship pre-compiled code的部分。
您需要通过在Jest
配置的react-navigation-tabs
选项中将其列入白名单来告诉transformIgnorePatterns
编译Jest
。
将jest.config.js
文件更改为如下所示,解决了OP中提到的问题。
但是“ react-native-reanimated
”模块(如another post中所述,它需要本地集成)需要进一步的工作,我们应该Mock
个具有此类本地要求的模块... >
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transformIgnorePatterns: [
"node_modules/(?!(react-native"
+ "|react-navigation-tabs"
+ "|react-native-splash-screen"
+ "|react-native-screens"
+ "|react-native-reanimated"
+ ")/)",
],
}
注意:transformIgnorePatterns
选项(由正则表达式组成的数组)最初旨在排除文件被编译的可能性,但是使用(?!(some-dir-name|another-name))
模式((?!...)
,消极的外观-ahead),我们确实告诉Jest
排除node_modules
目录中的所有内容,但我们确实指定了名称。
答案 3 :(得分:1)
在配置文件(.babelrc.js或package.json)中的某些地方,必须将“预设”下的“模块”设置为“ amd”之一。 “ umd” | “ systemjs” | “ commonjs” | “ cjs” | “汽车” |错误。
文档中的引荐来源this fragment
类似这样:
df['col1'] = np.where(df['col2'].str.contains('apple'), df['col1'] * 2, df['col1'])
答案 4 :(得分:1)
如果您不仅使用 React Native 还使用 Expo,我按照官方指南 Testing with Jest 修复了相同的问题,但针对 Expo 组件。具体来说,通过包管理器安装 jest 预设 jest-expo
,然后按照他们的描述更新我的 package.json:
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
]
}
我还需要在 transformIgnorePatterns
正则表达式字符串的末尾添加 |.*font.*
的例外,因为 Expo 字体给我带来了麻烦。可能我可以让它更具体一点,但我讨厌正则表达式,这很有效,所以我把它留在那里!
答案 5 :(得分:0)
我正在使用react-native-web,解决此问题的方法是将react-native-web
预设添加到我的jest.config.js中:
module.exports = {
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
timers: 'fake',
testPathIgnorePatterns: [
'<rootDir>/build/',
'<rootDir>/node_modules/',
'<rootDir>/rndemo/build/',
],
globals: {
'ts-jest': {
diagnostics: {
warnOnly: true,
},
},
},
preset: 'react-native-web',
}
答案 6 :(得分:0)
将 babel.config.js 修改为以下对我有用。此外,预设应首先出现,然后是所有其他配置。
module.exports = {
presets: [['@babel/preset-env',{targets: {node:
'current',},loose:true,},],],
}